“并发”指gc线程与用户线程时间重叠、仅短暂stw以保低延迟;“并行”指多gc线程协同工作但用户线程全程stw以提吞吐量;二者维度不同,可共存于同一收集器(如g1)。

在JVM垃圾收集器语境中,“并发”与“并行”不是按CPU核心数量划分的执行效果,而是由线程协作关系的主体不同决定的——前者关注GC线程与用户线程是否重叠运行,后者关注多个GC线程之间是否协同工作。多核CPU只是实现条件,不是定义依据。
并发(Concurrent):用户线程与GC线程的时间重叠
并发的核心是“不全程停顿”。它不要求多核,也不保证物理同时执行;只要GC阶段中用户线程能继续运行(哪怕只是部分阶段、哪怕在单核上靠时间片穿插),就属于并发。
- 典型行为:仅在初始标记、重新标记等极短环节触发STW,其余阶段(如并发标记、并发清理)用户线程照常执行
- 关键判据:用户线程是否被允许“抢时间”——即使GC线程和用户线程交替跑在同一核上,也满足并发定义
- 代表收集器:CMS(已废弃)、G1(默认并发模式)、ZGC、Shenandoah
并行(Parallel):多个GC线程之间的协同加速
并行的本质是“多线程合力干活”,重点在GC内部线程间的并行化,与用户线程状态无关。它依赖多核以提升吞吐,但定义本身不取决于是否多核——只要多个GC线程被调度到不同核心上同步执行,就是并行。
一款AI工具,主要用于使用 Codex CLI 进行深度网络搜索,适用于需要多源综合分析的复杂查询。当 `web_search`(Brave)返回结果不足,或用户……时使用,适合需要提升相关任务效率的用户。
- 典型行为:所有GC工作由多个线程并行完成,但整个过程用户线程全程冻结(STW)
- 关键判据:GC任务是否被拆分给多个线程同时处理——哪怕只用2个线程在双核上跑,也算并行
- 代表收集器:Parallel Scavenge、Parallel Old、ParNew
二者可共存,但逻辑层级不同
一个收集器可以同时具备并发与并行特性,因为它们描述的是不同维度的关系:
- G1既使用多线程并行执行标记/复制(并行),又允许用户线程在多数阶段运行(并发)
- “并行”回答的是“GC自己怎么干得快”,“并发”回答的是“GC干的时候,应用能不能继续跑”
- 不存在“更高级”或“互斥”的关系——它们解决的问题不同,设计目标也不同:并行追求吞吐量,发追求低延迟
常见误解澄清
不能因“多核”就默认是并发,也不能因“单核”就否定并行可能性(理论上单核多线程仍可称并行,只是无实际加速)。真正区分标准始终是:
- 用户线程是否被强制等待 → 决定是否“并发”
- GC任务是否由多个线程分工承担 → 决定是否“并行”
- 串行(Serial)既不并行(单GC线程),也不并发(全程STW),它是独立基准线










