并行指gc线程间多线程协同工作但用户线程全部暂停,适用于吞吐量优先场景;并发指gc线程与用户线程交替或同时运行,仅极短stw,旨在降低延迟。

并行和并发在 Java 垃圾收集器中不是同义词,区分的关键不在于“是否同时运行”,而在于谁和谁同时运行、是否暂停用户线程。
并行(Parallel):多条 GC 线程之间协同,但用户线程全停
并行描述的是垃圾收集器内部多个线程之间的关系。比如 ParNew、Parallel Scavenge、Parallel Old 收集器启动时,会启用多个 GC 工作线程,它们在多个 CPU 核心上真正同时执行标记、复制或整理等任务,从而加快单次 GC 的执行速度。
但关键约束是:整个过程中,所有用户线程(即你的 Java 应用线程)必须完全暂停(Stop-The-World)。无论 GC 线程跑得多快,应用逻辑在这段时间内彻底冻结。
- 本质是“用更多资源换更短 STW 时间”
- 适合吞吐量优先场景(如批处理、后台计算)
- 不解决响应延迟问题,只优化 GC 本身耗时
并发(Concurrent):GC 线程与用户线程交替/同时运行,用户线程不长期暂停
并发描述的是垃圾收集线程与用户线程之间的关系。典型代表是 CMS(已废弃)和 G1(部分阶段)、ZGC、Shenandoah。
这类收集器设计目标是让 GC 工作尽可能与应用运行重叠。例如:
- G1 的初始标记和并发标记阶段,用户线程可继续执行
- ZGC 的所有 GC 阶段都允许用户线程运行(仅极短的几毫秒 STW)
- CMS 在并发标记、并发预清理、并发清除阶段,用户线程照常服务请求
注意:“并发”不要求物理并行——即使在单核 CPU 上,通过时间片切换实现交替执行,也属于并发;但实际中,现代并发收集器通常会利用多核来提升并发效率。
一个类比帮你记住核心差异
想象厨房里有厨师(用户线程)和保洁员(GC 线程):
- 串行:1 个保洁员,厨师全程停工
- 并行:5 个保洁员一起打扫,但厨师仍要全部离场等待
- 并发:保洁员边擦地边收碗,厨师在另一侧灶台继续炒菜(可能偶尔被叫停半秒配合检查)
常见误区澄清
❌ “并发收集器一定比并行收集器快” —— 不对。并发带来额外同步开销和内存占用,吞吐量可能反而略低。
❌ “并行 = 并发” —— 概念层级不同:并行讲的是 GC 线程间的执行方式;并发讲的是 GC 线程与用户线程的协作关系。
✅ G1 和 ZGC 是“并发为主、部分并行”的混合设计:它们既用多线程并行执行 GC 子任务,又保证大部分时间用户线程不中断。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











