phaser的核心是让线程在每个阶段末尾同步收工与开工,通过阶段编号(phase)驱动节奏,支持动态注册注销、自动阶段推进、运行时伸缩及自定义阶段控制逻辑。

Phaser 的核心不是让线程“一起出发”,而是让它们在每个阶段末尾“一起收工、一起开工”。它用阶段编号(phase)驱动节奏,靠参与者动态注册与注销支撑弹性,天然适合构建有明确阶段划分、线程数量可能变化的协作任务模型。
阶段推进靠到达行为自然触发
每个阶段的结束不靠外部指令,而由线程调用 arriveAndAwaitAdvance() 触发。该方法做两件事:标记自己已到达当前阶段,并阻塞等待——直到所有当前已注册的参与者都完成这一步,Phaser 才自动将 phase +1,并唤醒全部等待线程。阶段号从 0 开始,首次调用后进入 phase 1,后续依此类推。线程无需记住数字,只需在业务逻辑完成点统一调用即可。
- 若只需上报不等待,可用 arrive(),比如记录日志或埋点
- 主线程可通过 getPhase() 实时读取当前阶段,用于监控或条件判断
- 调用 awaitAdvance(int phase) 可让某线程等待指定阶段结束,适合主控线程协调节奏
参与者数量支持运行时伸缩
Phaser 不要求初始人数固定,也不限制线程生命周期与同步器绑定。新线程启动时调用 register() 即加入当前及后续阶段;任务完成或失败时调用 arriveAndDeregister(),既完成当前阶段又退出后续同步,避免空等。批量场景可用 bulkRegister(n) 预分配。
- 注册/注销操作线程安全,多线程并发调用无状态风险
- 未显式注销的线程,随其所属任务实例结束,Phaser 自动回收,不泄漏
- 适合分片数动态变化、节点故障熔断、资源按需启停等真实调度场景
阶段切换可嵌入自定义控制逻辑
重写 onAdvance(int phase, int registeredParties) 方法,就能在每次 phase 推进前插入检查或动作。参数 phase 是刚完成的阶段号,registeredParties 是下一阶段预计参与数。返回 true 表示终止 Phaser,后续 arrive 调用立即失败;返回 false 继续下一阶段。
- 可用于校验中间结果是否达标,不满足则提前终止整个流程
- 可触发清理资源、写入审计日志、上报监控指标
- 结合 phase 编号,实现不同阶段差异化策略,如 phase=0 做初始化,phase=2 做聚合汇总
主线程可作为协调者深度参与
Phaser 不区分“工作线程”和“控制线程”,主线程同样能注册、等待、注销。常见模式是:主线程先创建 new Phaser(1) 占位,再启动子任务并让它们 register();关键节点调用 awaitAdvance(phaser.getPhase()) 等待全体就绪;任一子任务异常时,主线程可调 forceTermination() 快速中断,其余线程收到异常并退出。
- 这种主从结构便于构建可观察、可干预的任务编排链路
- 单次任务应使用独立 Phaser 实例,避免复用导致阶段错乱或状态污染
- 推荐以 taskID 或 triggerTime 为标识创建 Phaser,严格对齐任务生命周期











