phaser 是支持动态增减线程、自动推进阶段、分层协同的多阶段同步工具;推荐用 new phaser() 初始化后调用 register() 动态注册,以 arriveandawaitadvance() 同步阶段,用 arriveandderegister() 退出,通过重写 onadvance() 控制流程终止。

Java 的 Phaser 是专为多阶段、动态线程任务同步设计的同步工具,它不像 CountDownLatch 那样一次性,也不像 CyclicBarrier 那样固定参与数——它支持运行时增减线程、自动推进阶段、分层协同,适合真实业务中任务数量不确定、流程分阶段、角色可退出的场景。
初始化空 Phaser,避免预设线程数
不要用 new Phaser(n) 初始化固定参与者数量,除非你 100% 确定所有线程启动前就全部就位。更推荐:
- 用
new Phaser()创建一个空 phaser,初始注册数为 0 - 让每个任务线程在真正开始工作前调用
phaser.register()自行注册 - 这样能应对从队列拉取子任务、递归分治、响应式触发等动态场景
用 arriveAndAwaitAdvance() 控制阶段同步节奏
这是最常用的阶段等待方式,表示“我完成了本阶段,现在等所有人齐了再一起进下一阶段”:
- 每个线程在阶段结束处调用
int nextPhase = phaser.arriveAndAwaitAdvance(); - 返回值是下一阶段编号(从 0 开始),可用于日志或条件判断
- 若当前阶段无人未到达,该方法立即返回;否则阻塞直到全部到达
- 注意:必须先
register()才能调用,否则抛IllegalStateException
按需注册与主动退出,适配不同角色生命周期
不是所有线程都参与全部阶段。比如预处理线程只做第 0 阶段,聚合线程从第 1 阶段才加入:
- 新任务加入:调用
phaser.register()或phaser.bulkRegister(3) - 任务完成并退出后续阶段:调用
phaser.arriveAndDeregister() - 该操作会减少当前阶段所需到达数,并可能触发阶段自动推进
- 例如质检员完成检查后离开,不再参与打包阶段
监听阶段切换或终止流程,靠重写 onAdvance()
onAdvance(int phase, int registeredParties) 是受保护方法,在每个阶段结束、准备进入下一阶段时被调用:
- 返回
false:正常进入下一阶段(phase + 1) - 返回
true:Phaser 进入终止状态,后续awaitAdvance立即返回,arrive类方法抛异常 - 常用于:执行完第 2 阶段后自动结束、某阶段失败时中止整个流程、打印阶段统计信息
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











