Phaser支持动态增减线程、自动推进阶段及自定义阶段逻辑,需用arriveAndAwaitAdvance()同步、onAdvance()控制流转、deregister()及时退出。

Phaser 适合把一个大任务拆成多个阶段,让线程按阶段协作推进。它不像 CountDownLatch 那样只能用一次,也不像 CyclicBarrier 那样固定人数——它支持动态增减线程、自动推进阶段、还能在阶段切换时插入自定义逻辑。
阶段划分与参与者注册要匹配实际流程
每个阶段的“等待完成”动作,只对当前已注册的参与者生效。如果某个线程中途加入或退出,会影响该阶段的同步条件:
- 初始化 Phaser 时可设为
new Phaser(0),后续由各线程自行调用register()注册,适合启动节奏不一致的场景 - 若所有工作线程能统一启动,直接用
new Phaser(n)指定初始数量更简洁,避免遗漏注册 - 批量注册用
bulkRegister(int n),比循环调用register()更高效,尤其适用于预分配大量 Worker 的情况
阶段同步必须用 arriveAndAwaitAdvance() 配合阶段计数
单靠 arrive() 只是通知完成,不会阻塞;真正实现“等齐再走”的是 arriveAndAwaitAdvance()。它的返回值是下一阶段编号,可用于判断当前所处阶段:
- 阶段编号从 0 开始递增,第一次调用后进入阶段 1,第二次进入阶段 2……
- 可在循环中用
int phase = phaser.arriveAndAwaitAdvance(); if (phase == 2) { /* 第三阶段特殊处理 */ } - 注意:若某线程未注册就调用该方法,会抛出
IllegalStateException
阶段结束逻辑靠 onAdvance() 控制流转与终止
重写 onAdvance(int phase, int registeredParties) 是控制阶段行为的关键入口。它在所有线程完成当前阶段、准备推进前被自动调用:
- 返回
false表示继续下一阶段(默认行为) - 返回
true表示终止 Phaser,后续awaitAdvance()调用将立即返回,适合任务自然结束或异常熔断 - 可在此方法中做清理、日志、状态检查,例如:
if (phase == 2 && registeredParties == 0) return true;表示第三阶段完成后无剩余参与者,主动收尾
线程退出需主动 deregister 避免干扰后续阶段
一个线程完成全部阶段后,应调用 arriveAndDeregister(),否则它仍会被计入下一阶段的同步条件,导致其他线程无限等待:
- 推荐在
finally块中执行注销,确保异常也不会漏掉 - 若使用
arriveAndAwaitAdvance()后立刻注销,需注意:注销操作本身不参与阶段等待,但会影响下一阶段的参与者总数 - 主线程如仅作协调用途(如启动 Worker、收集结果),可注册后不参与计算,仅用
awaitAdvance()监听阶段变化

















