phaser 是 java 中支持多阶段协作的动态同步工具,通过按需注册、arriveandawaitadvance 阶段同步、arriveandderegister 退出及父子嵌套机制实现灵活调度。

Phaser 是 Java 并发编程中专为多阶段协作设计的同步工具,它不靠预设线程数,而是通过动态注册、隐式阶段推进和父子嵌套机制,实现灵活的任务调度。关键在于让每个任务在合适时机“加入”、“到达”和“退出”,而不是强行统一生命周期。
按需注册参与者,避免硬编码数量
初始化 Phaser 时不要直接 new Phaser(5),除非你百分百确定参与者数量固定且全程不变。多数真实场景(如从队列拉取子任务、递归分治、响应式工作流)中,任务数是运行时才明确的。
- 用 new Phaser() 或 new Phaser(null, 0) 启动一个空 phaser
- 每个新任务启动前调用 phaser.register(),为其分配独立槽位
- 切忌在未 register 前调用 arrive(),否则抛 IllegalStateException
用 arriveAndAwaitAdvance 控制阶段节奏
这是最常用的同步入口:线程完成本阶段工作后调用它,会阻塞直到所有当前注册参与者都到达,然后自动进入下一阶段,并返回新阶段号。
- 适合所有参与者全程参与的场景,例如三阶段流水线(准备→处理→汇总)
- 主线程也可调用,用于协调整体流程,比如等待全部 worker 完成第 0 阶段后再触发第 1 阶段动作
- 阶段编号从 0 开始,每次推进 +1,可通过 phaser.getPhase() 获取当前值
阶段性退出:用 arriveAndDeregister 精准释放资源
不是所有任务都要走完全部阶段。有些线程只负责预处理,有些只做结果聚合,这时要用 arriveAndDeregister() 主动退出。
- 调用后该线程不再参与后续阶段,同时减少总参与者数
- 能触发阶段自动推进(只要剩余未到达数归零),适合“Map-Reduce”类结构
- 例如:一组 worker 完成计算后注销,仅留一个 collector 等待它们全部抵达并开始汇总
构建层次化协同:父子 Phaser 分层管理
当任务天然分组(如多个计算组各自同步,再由主控协调),可借助父子 Phaser 形成树状结构,降低全局竞争压力。
- 创建父 phaser:Phaser root = new Phaser();
- 每组新建子 phaser:Phaser group = new Phaser(root); —— 构造时传入 parent
- 子 phaser 每完成一个 own phase,会自动为父 phaser 调用 arrive(),父阶段推进代表“所有子组已就绪”
- 这种结构天然适配分布式任务拆分、批量作业分片等场景











