phaser是java中专为分阶段、动态参与者设计的同步工具,需显式调用arrive*方法推进阶段,支持register/deregister动态调整线程数,并通过onadvance控制阶段生命周期。

Phaser 是 Java 并发编程中专为「分阶段 + 动态参与者」场景设计的同步工具。它不靠固定人数锁死流程,而是让线程自主决定何时加入、何时退出、在哪一阶段做何事。用对了,就能自然支撑 MapReduce 式流水线、插件化工作流、多批次压测等真实业务模型。
阶段推进必须基于显式抵达
Phaser 不会自动感知线程执行进度,所有同步行为都依赖 arriveAndAwaitAdvance() 或 arriveAndDeregister() 这类显式调用:
- 每个线程在完成当前阶段任务后,必须调用一次 arrive* 方法,否则该线程不计入本阶段计数
- 仅调用 arrive() 表示“我到了”,但不等待;若需全体同步再继续,必须用 arriveAndAwaitAdvance()
- 构造时传入初始数量(如
new Phaser(3))等价于主线程已为 3 个线程完成注册,但工作线程仍需自行 register() 才能参与后续阶段 - 未注册就调用 arrive* 会抛
IllegalStateException: Not registered
动态调整参与者要配对操作
增减线程数不是配置开关,而是状态变更,需保持 register / deregister 的逻辑平衡:
- 新线程启动前调用 phaser.register(),确保其被纳入下一阶段计数
- 某线程完成第 n 阶段后不再参与后续,就在该阶段末尾调用 arriveAndDeregister() —— 这是“抵达+注销”原子操作,比先 arrive 再 deregister 更安全
- 避免在循环中反复 register 却不 deregister,否则
getRegisteredParties()持续增长,导致 arriveAndAwaitAdvance() 永远无法满足条件 - 主线程若作为协调者,也应参与注册与注销,否则 Phaser 可能因残留注册数无法自然终止
用 onAdvance 控制阶段生命周期
onAdvance(int phase, int registeredParties) 是阶段切换的钩子,适合做清理、判断或终止决策:
- 返回 true 表示终止 Phaser,后续 arrive* 调用将立即返回(不再阻塞),常用于“第三阶段完成后整体收工”
- 返回 false 表示正常进入下一阶段,Phaser 自动递增 phase 编号
- 不要在 onAdvance 中调用另一个 Phaser 的 arrive* 方法,也不应执行 I/O、锁等待或耗时计算,否则会阻塞整个阶段推进
- 可结合
getPhase()做阶段特异性处理,例如 phase == 2 时检查校验结果是否达标,不达标则返回 true 强制中止
典型分阶段协作结构
以“5 线程预加载 → 3 线程校验 → 1 线程提交”为例,关键不在写多少代码,而在控制谁在哪个 phase 到达:
- 初始化:
Phaser phaser = new Phaser(5)(第一阶段默认 5 人) - 阶段一:全部 5 线程调用
arriveAndAwaitAdvance(),phase 从 0→1 - 阶段二前:2 个线程调用
arriveAndDeregister(),剩下 3 人继续arriveAndAwaitAdvance(),phase 从 1→2 - 阶段三前:再有 2 人调用
arriveAndDeregister(),仅剩 1 人调用arriveAndAwaitAdvance(),phase 从 2→3 - 可在 onAdvance 中判断 phase == 3 时返回 true,结束整个同步流程











