Phaser是Java中灵活的多阶段同步工具,支持动态注册线程、分阶段推进和重复使用。通过register注册线程,arriveAndAwaitAdvance实现阶段同步,适用于多轮协同任务如游戏回合或数据处理流程。

Phaser 是 Java 并发包 java.util.concurrent 中的一个同步工具,用于控制多个线程分阶段执行。相比 CountDownLatch 和 CyclicBarrier,Phaser 更加灵活,支持动态注册线程、多阶段同步以及可重用的屏障机制。
Phaser 的基本原理
Phaser 允许多个线程在多个阶段(phase)中同步。每个阶段所有参与线程必须到达屏障点后,才能进入下一阶段。Phaser 支持以下特性:
- 动态注册/注销线程(通过 register() 和 arriveAndDeregister())
- 每个阶段自动推进,无需重复初始化
- 支持批量等待和单个线程等待
基本使用步骤
使用 Phaser 控制线程阶段主要分为三步:创建 Phaser、注册线程、在每个阶段调用同步方法。
1. 创建 Phaser 实例可以指定初始参与线程数量,也可以动态添加。
立即学习“Java免费学习笔记(深入)”;
Phaser phaser = new Phaser(); // 初始无参与者
2. 线程注册并等待阶段完成每个线程需要先注册自己,然后在每个阶段调用 arriveAndAwaitAdvance() 来等待其他线程。
示例代码:
class Worker implements Runnable {
private final Phaser phaser;
Worker(Phaser phaser) {
this.phaser = phaser;
phaser.register(); // 注册当前线程
}
public void run() {
try {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + " 到达第 " + i + " 阶段");
phaser.arriveAndAwaitAdvance(); // 等待所有线程到达
System.out.println(Thread.currentThread().getName() + " 完成第 " + i + " 阶段");
}
} finally {
phaser.arriveAndDeregister(); // 任务完成,注销
}
}
}
3. 启动多个线程进行阶段同步在主线程中创建并启动多个工作线程:
public class PhaserExample {
public static void main(String[] args) {
Phaser phaser = new Phaser();
for (int i = 0; i < 3; i++) {
new Thread(new Worker(phaser)).start();
}
}
}
常用方法说明
Phaser 提供多种同步方式,适应不同场景:
- arriveAndAwaitAdvance():线程到达并等待其他线程完成当前阶段
- arriveAndDeregister():线程到达并注销,不再参与后续阶段
- register():动态增加一个参与者
- getPhase():获取当前阶段编号(从 0 开始)
- bulkRegister(n):批量注册 n 个参与者
实际应用场景
Phaser 特别适用于需要多轮协同的任务,例如:
- 模拟多轮游戏(每轮玩家行动后统一结算)
- 分阶段数据处理(如加载、计算、输出)
- 测试并发性能时控制各阶段启动时间
比如在游戏中控制所有玩家完成移动后再进入战斗阶段:
phaser.arriveAndAwaitAdvance(); // 所有玩家移动完成 // 进入战斗逻辑 phaser.arriveAndAwaitAdvance(); // 战斗结束,准备下一轮基本上就这些。Phaser 的灵活性让它成为控制多阶段并发执行的强大工具,合理使用能简化复杂的同步逻辑。










