Phaser是支持动态参与者和显式阶段推进的同步器,核心价值在于阶段可编程、线程可进退、同步点可定制;其phase从0递增,由arriveAndAwaitAdvance()触发推进,支持运行时register/bulkRegister/arriveAndDeregister调整参与者,并可通过重写onAdvance自定义阶段流转逻辑。

Phaser不是“增强版的CyclicBarrier”,而是一种支持动态参与者和显式阶段推进的同步器。它真正价值在于:阶段可编程、线程可进退、同步点可定制——这三点让多阶段任务协调变得可控且贴近业务逻辑。
阶段推进机制与phase编号含义
Phaser的phase从0开始递增,每次调用arriveAndAwaitAdvance()成功后,当前阶段结束、下一阶段自动开启,返回值即为新阶段编号。注意:phase不是计数器,而是状态快照;同一阶段内多次调用awaitAdvance(phase)不会阻塞重复等待。
- 主线程调用
arriveAndAwaitAdvance()后,phase+1,所有已注册线程必须完成该阶段才能推进 - 若某线程未调用
arrive*系列方法,它不参与该阶段同步,但会“滞留”在旧phase,后续awaitAdvance()可能立即返回(因phase已变) - 可通过
getPhase()实时读取当前阶段,但不能直接修改;阶段变更只由arriveAndAwaitAdvance()或forceTermination()触发
动态参与者管理的关键操作
Phaser的灵活性核心在于运行时调整参与线程数。注册与注销不是“加减法”,而是影响阶段推进条件的契约行为。
-
register():新增1个待同步线程,返回当前phase;适用于启动时未知数量、或中途加入的新工作线程 -
bulkRegister(n):比n次register()更高效,适合批量启动任务(如分片处理中预分配10个worker) -
arriveAndDeregister():完成当前阶段后退出,不再参与后续任何阶段;适合“一次性任务者”,如初始化线程、清理线程 - 注销后,
getRegisteredParties()立即减少,下一次arriveAndAwaitAdvance()只需等待剩余参与者
onAdvance():自定义阶段流转逻辑
重写onAdvance(int phase, int registeredParties)是Phaser区别于其他同步器的核心能力。它在**每个阶段正式结束、下一阶段尚未开始前**被调用,返回true表示终止Phaser,false表示继续。
- 可用于日志记录:“阶段2完成,共5人参与”
- 可做阶段校验:若phase==1但registeredPartiestrue终止流程并抛异常
- 可触发外部动作:阶段0结束时加载配置,阶段2结束时汇总中间结果
- 注意:该方法在Phaser内部锁保护下执行,避免耗时操作或阻塞调用
典型实战陷阱与规避建议
Phaser易用,但几个细节不注意会导致“看似同步、实则错乱”。
-
主线程未注册就调用awaitAdvance:构造时传入
new Phaser(1),或首次调用前显式register(),否则主线程不算参与者,阶段可能提前推进 -
线程注册后未调用arrive*:该线程永远卡在当前phase,导致其他线程无限等待;建议配合try-finally确保
arriveAndAwaitAdvance()或arriveAndDeregister()必达 -
忽略终止状态检查:调用
awaitAdvance()前应先判断!isTerminated(),否则可能陷入无意义等待 - 父子Phaser误用:子Phaser注销时会通知父Phaser,若父Phaser未设计好层级策略,可能导致父级提前终止;仅在大规模分组协调(如集群节点分Region同步)时启用层级


















