Phaser是动态绑定、阶段驱动的线程协调器,核心在于解耦推进节奏与参与者管理;阶段靠arriveAndAwaitAdvance()同步推进,注册/注销须匹配任务生命周期,onAdvance()支持阶段编排,主线程可作为协调者主导流程。

Phaser不是“一次性屏障”,也不是固定人数的等待点,它是一个以阶段编号(phase)为驱动、参与者动态绑定、生命周期与任务对齐的本地线程协调器。它的核心在于把“推进节奏”和“谁参与”彻底解耦——阶段自动演进,而注册/注销完全运行时可控。
阶段推进靠 arriveAndAwaitAdvance(),不是 arrive()
每个线程完成当前阶段工作后,必须调用 arriveAndAwaitAdvance() 才算真正同步点:
- 该方法会先标记自身到达,再阻塞等待——直到所有当前已注册的参与者都调用了它,Phaser 才自动将 phase +1,并唤醒全部线程
- 返回值是下一阶段编号(从 0 开始,首次调用后进入 phase 1),可用于做阶段特判,比如 if (phaser.arriveAndAwaitAdvance() == 2) { /* 第三阶段专属逻辑 */ }
- 仅调用 arrive() 是异步上报,不阻塞,适合埋点或状态通知,但不能构成阶段同步
- 未注册就调用会抛 IllegalStateException,务必确保 register() 先于同步操作
参与者管理必须匹配任务流,不能“一注永逸”
Phaser 的弹性正体现在运行时增减能力,但需主动配合业务生命周期:
- 新线程启动即调用 register(),立即成为当前及后续阶段的参与者
- 线程完成全部任务后,必须调用 arriveAndDeregister() ——既表示本阶段完成,又解除与后续阶段的绑定
- 推荐在 finally 块 中注销,防止异常导致“幽灵参与者”滞留,拖慢甚至卡死下一阶段
- 批量预分配场景用 bulkRegister(n),比循环 register() 更高效,避免 CAS 竞争开销
阶段切换逻辑由 onAdvance() 控制,是流程编排的关键入口
重写 onAdvance(int phase, int registeredParties) 可在每次阶段推进前插入自定义行为:
- phase 是刚结束的阶段号(如 phase=2 表示第二阶段已完成)
- registeredParties 是下一阶段预计参与数,可用于判断是否还有线程待执行
- 返回 false(默认)继续下一阶段;返回 true 则终止 Phaser,后续 await 操作立即返回
- 典型用途:阶段耗时打点、中间结果校验、失败熔断(如某阶段数据异常则 return true)、资源清理、或检测无参与者时自然收尾
主线程可作为协调者,不参与计算但掌控节奏
Phaser 不区分“主”“从”,主线程同样能注册并主导流程:
- 初始化时可设 new Phaser(1),让主线程先占位,再启动子线程并令其 register()
- 主线程可在关键节点调用 awaitAdvance(phaser.getPhase()),监听阶段变化而不执行计算任务
- 若子任务异常,主线程可调用 forceTermination() 强制中断,避免其他线程无限等待
- 整个任务实例结束后,Phaser 实例随 GC 自动回收,无需手动清理

















