Phaser 是 Java 并发包中支持动态增减参与者的灵活同步屏障工具;它以阶段计数器为核心,通过 register() 和 arriveAndDeregister() 动态调整参与者,配合 arriveAndAwaitAdvance() 实现多阶段协作。

Phaser 是 Java 并发包(java.util.concurrent)中一个灵活的同步屏障工具,特别适合需要动态增减参与线程(即“参与者”)的场景。它比 CyclicBarrier 和 CountDownLatch 更加通用:支持分阶段同步、可重用、且允许在运行时注册或注销参与者。
理解 Phaser 的核心机制
Phaser 的本质是一个“阶段计数器”,每个阶段(phase)必须等到所有已注册的参与者都到达(arriveAndAwaitAdvance())才推进到下一阶段。关键在于:参与者数量不是固定初始化的,而是通过 register() 和 arriveAndDeregister() 动态调整。
初始构造时可指定预估参与者数(如 new Phaser(3)),也可无参构造(初始参与者为 0),之后由线程主动调用 register() 加入。
动态添加参与者:register() 的正确用法
新线程想加入同步,应在执行任务前调用 phaser.register()。该方法原子性地将当前线程注册为一个新参与者,并返回注册后的当前阶段号。
立即学习“Java免费学习笔记(深入)”;
- 注册后,该线程必须在每个阶段至少调用一次到达方法(如
arriveAndAwaitAdvance()或arrive()),否则会阻塞其他线程推进 - 避免在已到达当前阶段后再注册——应确保注册发生在进入同步逻辑之前,例如在循环开始前或任务入口处
- 示例:工作线程启动时注册
动态移除参与者:arriveAndDeregister()
当某个线程完成全部任务、不再参与后续阶段时,应调用 arriveAndDeregister()。它表示“我到达本阶段,并从此退出 Phaser”。调用后,该线程不再计入下一阶段的参与者计数。
- 常见于线程处理完一批数据后主动退出;或异常退出前清理注册
- 注意:不能在未到达当前阶段时就 deregister,否则可能破坏同步逻辑
- 典型模式是:到达 → 执行业务 → 判断是否退出 → deregister(若退出)
配合阶段控制实现多轮协作
Phaser 天然支持多阶段协作。每次调用 arriveAndAwaitAdvance() 都会阻塞直到所有当前注册参与者到达,然后自动进入下一阶段(phase 自增)。你可以利用 getPhase() 获取当前阶段号做差异化处理。
- 阶段号从 0 开始,每完成一轮同步 + 推进,phase 加 1
- 用
phaser.getRegisteredParties()实时查看当前注册数,辅助决策(比如剩余 1 人时提前结束) - 可结合
onAdvance(int phase, int registeredParties)重写钩子函数,在阶段切换时执行清理、检查或终止逻辑(返回 true 表示终止 Phaser)


















