phaser阶段由参与者抵达隐式驱动,无需手动递增;所有已注册参与者调用arrive类方法使未抵达数归零时,phase自动+1,新阶段中仍注册者自动进入。

Phaser 的阶段控制不是靠手动递增变量实现的,而是由参与者到达行为隐式驱动的。只要当前所有已注册的参与者都完成本阶段并调用 arrive 类方法,Phaser 就自动推进到下一阶段(phase + 1),整个过程无需外部干预或状态维护。
阶段自动推进机制
Phaser 的“阶段”本质是一个只读整数(从 0 开始),它的变化完全取决于参与者是否全部抵达当前阶段:
- 每次调用
arrive()、arriveAndAwaitAdvance()或arriveAndDeregister()都会触发一次“抵达计数” - 当未抵达参与者数(
getUnarrivedParties())降为 0 时,当前阶段结束,phase 自动 +1 - 新阶段开始后,所有仍注册的参与者(未 deregister 的)自动进入下一阶段,无需重新 register
- 主线程若提前注册(如
new Phaser(1)),它也参与计数和推进,必须显式arriveAndDeregister()才能退出协调
动态参与者与阶段对齐
不同线程可参与不同数量的阶段,关键在于注册时机与退出时机的配合:
- 任务启动前调用
phaser.register()—— 确保它被计入当前阶段的抵达目标 - 仅需参与部分阶段的任务,在最后一阶段末尾调用
arriveAndDeregister(),既完成抵达又退出后续同步 - 全程参与的任务每阶段调用
arriveAndAwaitAdvance(),阻塞等待全体完成后再继续 - 监控类线程可用
arrive()上报进度但不阻塞,避免拖慢主流程
父子Phaser构建层次化阶段流
当任务天然分组(如多个 worker 组并行处理再统一汇总),嵌套 Phaser 能让阶段推进更语义化:
- 父 Phaser 控制全局阶段(例如:Phase 0=各组启动,Phase 1=各组完成,Phase 2=结果聚合)
- 每个子组创建自己的 Phaser,并传入父 Phaser 构造:
new Phaser(parent) - 子 Phaser 每完成一个 own phase,会自动为父 Phaser 调用
arrive(),代表该组已就绪 - 父 Phaser 的
awaitAdvance(1)即表示“所有子组均已抵达 Phase 1”,适合 Map-Reduce 类编排
避免常见逻辑断裂点
阶段同步失效往往源于参与者生命周期管理不当:
- 禁止未 register 就 arrive —— 会抛
IllegalStateException: not registered - 避免在循环中反复 register 却不 deregister —— 导致抵达目标虚高,
arriveAndAwaitAdvance()永远无法返回 - 不要在
onAdvance()回调里调用其他 Phaser 的阻塞方法 —— 容易引发死锁 - 大量微任务频繁注册/注销时,考虑批量合并或换用
CompletableFuture链式编排,减少内部数组扩容开销











