phaser 通过 register()、arriveandderegister() 和父子嵌套机制实现动态多阶段并发同步,支持运行时增减参与者、隐式阶段推进及层次化协同,无需预设线程数。

Phaser 本身不叫“多阶段协同器”,但它的设计确实支持多阶段、动态参与的并发同步——关键在于利用 register()、arriveAndDeregister() 和分层 Phaser(parent-child)机制,而非预设固定线程数。
动态注册与注销:应对任务数量不确定
Phaser 允许在运行时动态增减参与者,适合任务数在执行中才确定的场景(例如:从队列拉取子任务、递归分治、响应式工作流)。
- 每个新任务开始前调用 phaser.register(),为它分配一个独立的到达计数槽位
- 任务完成时调用 phaser.arriveAndDeregister(),自动减少参与者总数并触发阶段推进(如果满足当前阶段阈值)
- 避免提前
new Phaser(n)固定初始数——那会限制灵活性;应使用new Phaser()或new Phaser(null, 0)启动空 phaser
多阶段推进:用 arrive() 控制阶段节奏
Phaser 的“阶段”(phase)是隐式递增的整数,每次所有当前注册参与者都到达后自动+1。你不需要手动管理 phase 变量,只需关注“谁该在哪一阶段同步”。
- 调用 phaser.arrive() 表示该线程完成本阶段工作,但不退出——仍参与后续阶段
- 若某任务只参与部分阶段(如预处理线程不参与结果聚合),就用 arriveAndDeregister() 提前退出
- 主线程可用 phaser.awaitAdvance(int phase) 等待特定阶段结束,例如:等待所有子任务完成第 0 阶段(分发完毕),再启动第 1 阶段(汇总)
嵌套 Phaser:构建层次化同步结构
当任务具有天然分组(如:多个 worker 组各自同步,再由组长统一协调),可让子 Phaser 注册到父 Phaser,形成树状协同:
- 创建父 Phaser:
Phaser root = new Phaser(); - 每组启动时新建子 Phaser:
Phaser group = new Phaser(root);—— 构造时传入 parent,子 phaser 完成其 own phase 时会自动为 parentarrive() - 这样,父 phaser 的阶段推进代表“所有子组均已抵达当前阶段”,天然支持 Map-Reduce 类模式
实用建议与避坑点
Phaser 强大但易误用,尤其在动态场景下:
- 别在未 register 前调用 arrive() —— 会抛 IllegalStateException
- 大量频繁 register/deregister 可能引发内部数组扩容开销,若任务粒度极小(如微秒级),考虑批量合并或换用其他原语(如 CompletableFuture.join() 链式编排)
- 调试时可用
phaser.getRegisteredParties()和phaser.getUnarrivedParties()实时观察状态,比日志更可靠 - Phaser 不是锁,不保证临界区互斥——需要共享数据保护时,仍需配合 synchronized 或原子变量










