Phaser的核心能力是“动态参与者+隐式阶段推进”,需显式register()注册、arriveAndDeregister()原子退出,phase由到达动作触发递增,主线程应精准awaitAdvance()而非盲目同步。

Phaser 的核心能力不是“多阶段同步”,而是“动态参与者 + 隐式阶段推进”的组合。它不依赖预设线程数,而是靠运行时显式注册、原子退出和阶段自动递增,自然适配任务规模浮动、角色分工不同的真实并发场景。
参与者必须显式注册,不能靠构造参数“占位”
写 new Phaser(5) 只是把内部计数器初始化为 5,并不代表已有 5 个合法参与者。没调 register() 就直接 arriveAndAwaitAdvance(),必然抛出 IllegalStateException: Not a registered party。
- 安全起点是
new Phaser()或new Phaser(null, 0),从零开始 - 每个工作线程启动后、执行任务前第一件事:调
phaser.register() - 主线程若参与(如汇总结果),也得自己
register();若只协调不干活,就不注册,改用awaitAdvance(int) - 批量注册可用
bulkRegister(n),比循环register()略快,但它仍是运行时动作,不是声明上限
阶段性退出必须原子完成,不能拆成两步
线程完成某阶段后不再参与后续流程,必须用 arriveAndDeregister() 一次性完成“到达 + 注销”。deregister() 根本不是 public 方法,分写 arrive() 和所谓注销是常见错误。
- 预处理线程加载完数据 → 立即调
arriveAndDeregister(),干净退出 - 汇总线程需等全部子任务结束 → 全程用
arriveAndAwaitAdvance()或配合awaitAdvance() - 错误模式:
arriveAndAwaitAdvance()后再调arriveAndDeregister()—— 前者已推进 phase,后者可能落在新 phase,导致计数错乱
阶段推进由“到达动作”触发,不是自动发生
Phaser 的 phase 号不会凭空递增。只有当已注册的参与者调用 arrive()、arriveAndAwaitAdvance() 或 arriveAndDeregister() 时,内部计数器才响应。未到达的线程不会推动阶段前进。
立即学习“Java免费学习笔记(深入)”;
- 每个
arriveAndAwaitAdvance()表示“我到了,且要等别人”,返回时 phase 已 +1 -
arrive()只完成“到达”,不等待;若需后续等待,必须搭配awaitAdvance(int) -
awaitAdvance(int phase)是非阻塞等待的起点:调用前必须先arrive()或arriveAndDeregister(),否则会永远卡住
主线程应做节奏控制器,而非盲目同步者
主线程通常不干活,只控制流程边界。它不该和工作线程一样调 arriveAndAwaitAdvance(),而应精准等待某个 phase 结束,再触发下一阶段动作。
- 启动子任务前记下当前 phase:
int p0 = phaser.getPhase() - 分发完所有任务后调
phaser.awaitAdvance(p0),确保全部抵达第 0 阶段 - 再启动第 1 阶段逻辑(如校验),避免“部分还没开始,主线程已往下冲”
-
awaitAdvance()不自动arrive(),调用者自己必须先完成到达动作


















