arriveandawaitadvance 是阶段协同推进机制,宣告完成、等待全员到达、同步进入下一 phase;其阻塞由 phaser 当前有效注册线程数决定,需配合超时使用以防死锁。

arriveAndAwaitAdvance 不是“暂停自己”,而是“宣告完成 + 等所有人完成 + 一起进下一阶段”的三合一动作。
它本质是阶段交接的确认信号
调用这个方法,线程在说三件事:
- “我当前 phase 的工作已做完”(完成宣告)
- “我现在不继续往下跑了,等其他注册线程也做完”(主动阻塞)
- “等齐了,我们一起跳到 phase+1,然后才各自执行下一阶段逻辑”(协同推进)
它不像 sleep 那样单纯停顿,也不像 wait 那样依赖 notify;它的阻塞完全由 Phaser 内部状态驱动——只看当前已注册的参与者是否全部调用过 arriveAndAwaitAdvance。
阻断是否发生,取决于“谁算数”
Phaser 只统计当前注册且未注销的线程。以下情况会导致看似“该等却没等”或“一直卡住”:
- 某线程忘了 register():它不参与计数,调不调 arriveAndAwaitAdvance 都不影响阻断逻辑
- 某线程提前 arriveAndDeregister():它退出后,剩余注册数变少,更易满足“全员到达”条件
- 主线程误删光所有参与者:phaser.getRegisteredParties() 变为 0,后续 arriveAndAwaitAdvance 直接返回负 phase(终止态),不再阻塞
所以阻断是否生效,不是看代码写了没写,而是看 Phaser 当前维护的有效注册名单。
它控制的是阶段粒度的执行节奏
每个 arriveAndAwaitAdvance 调用都对应一个明确的 phase 边界:
- 第一次调用 → 等待 phase 0 完成,进入 phase 1
- 第二次调用 → 等待 phase 1 完成,进入 phase 2
- phase 编号从 0 开始递增,但它是结果(刚完成的阶段号),不是输入条件
你不能靠 if (phaser.getPhase() == 2) 来分支业务逻辑,而应把不同阶段的处理逻辑写在 arriveAndAwaitAdvance 前后——因为阻断发生的位置,就是阶段切换的精确锚点。
必须搭配超时使用以防死锁
没有超时的 arriveAndAwaitAdvance 是危险的:
- 某个线程因异常、阻塞或逻辑遗漏没调用,其余线程将永久等待
- 推荐始终使用 awaitAdvanceInterruptibly(int phase, long timeout, TimeUnit unit) 或带超时的 arriveAndAwaitAdvance(long timeout, TimeUnit unit)
- 超时后可做清理、日志、重试或主动 deregister,避免整个流程僵死
阻断本身不可怕,可怕的是没人知道它为什么没结束。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











