phaser 是可重用、可动态增减参与者的多阶段协调器,支持运行时注册/注销线程、自动推进阶段及阶段变化监听;而 countdownlatch 是一次性门闩,无法重置或调整参与者数量。

Phaser 是什么,为什么比 CountDownLatch 更适合多阶段协同
CountDownLatch 本质是一次性门闩,计数归零后无法重置,所有线程只能等一个固定屏障点。而 Phaser 是可重用、可动态增减参与者的“阶段协调器”——它天然支持多轮、多阶段协作,每个阶段结束自动进入下一阶段,还能在运行时注册新线程或注销已退出线程。
用 Phaser 实现多阶段同步(替代多个嵌套 CountDownLatch)
假设任务分三阶段:准备 → 计算 → 汇总,每阶段都需所有活跃线程到达后才推进,且不同线程可能在不同阶段加入或退出:
- 创建 Phaser 时不设初始参与者数:
Phaser phaser = new Phaser(); - 每个线程在进入第一阶段前调用
phaser.register()注册自己 - 每阶段末尾调用
phaser.arriveAndAwaitAdvance()—— 这会阻塞直到本阶段所有已注册线程都到达,然后自动进入下一阶段(phase 编号 +1) - 某线程完成全部工作后调用
phaser.arriveAndDeregister(),它将不再参与后续阶段的等待
这样无需为每个阶段 new 一个 CountDownLatch,也不用手动管理多个 latch 的触发顺序和生命周期。
动态增减参与者:解决 CountDownLatch “人数写死”的硬伤
CountDownLatch 构造时必须指定 count,之后无法变更。而 Phaser 支持运行时灵活调整:
- 新线程启动后调用
phaser.register(),立刻成为下一阶段的参与者 - 子任务线程处理完自己的数据,调用
phaser.arriveAndDeregister(),自动从后续阶段剔除 - 可通过
phaser.getRegisteredParties()和phaser.getArrivedParties()实时观察状态
例如:主控线程启动 3 个计算线程 → 阶段 0 完成;随后根据中间结果再动态派生 2 个校验线程 → 它们 register 后,阶段 1 的等待人数就变成 5;校验线程完成后 deregister,阶段 2 就只剩原始 3 个线程继续推进。
监听阶段变化,实现阶段专属逻辑
通过继承 Phaser 并重写 onAdvance(int phase, int registeredParties),可在每次阶段跃迁时插入自定义动作:
- 返回
false表示继续下一轮(默认行为) - 返回
true表示终止 phaser(类似 CountDownLatch 的 final state) - phase 参数是刚完成的阶段编号(从 0 开始),可用于分支逻辑:if (phase == 1) { 启动汇总服务; }
- registeredParties 是下一阶段预期参与数,可用于资源预分配或日志记录
这种钩子机制让“阶段语义”真正落地,而不是靠外部变量 + 多个 if 判断模拟。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











