CyclicBarrier 是 Java 并发包中可重复使用的同步辅助类,用于让一组线程互相等待至全部到达栅栏后同时继续执行;支持屏障动作、超时与中断处理,适用于分阶段协同场景。

Java 中没有直接叫“并发阶段器”的内置类,但你提到的“可重复循环使用的多线程栅栏”,实际指的是 CyclicBarrier —— 它正是为这种场景设计的:让一组线程互相等待,直到全部到达某个同步点(即“栅栏”),然后一起继续执行,并且可以重复使用。
什么是 CyclicBarrier?
CyclicBarrier 是 Java 并发包(java.util.concurrent)中的一个同步辅助类。它和 CountDownLatch 类似,但关键区别在于:可重置、可重复使用。每次所有参与线程调用 await() 后,栅栏就“打开”,线程继续执行;之后它自动重置,等待下一轮。
基本用法:创建与等待
使用步骤很简单:
- 构造时指定参与线程数(例如 3 个线程协作)
- 每个线程执行到同步点时调用
barrier.await() - 当第 N 个线程调用
await(),所有线程同时被释放,继续向下执行
示例代码:
立即学习“Java免费学习笔记(深入)”;
CyclicBarrier barrier = new CyclicBarrier(3);
<p>for (int i = 0; i < 3; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " 开始工作");
// 模拟不同耗时任务
try { Thread.sleep((long)(Math.random() * 2000)); } catch (InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + " 到达栅栏");
try {
barrier.await(); // 阻塞,直到其他线程也到达
} catch (Exception e) { e.printStackTrace(); }
System.out.println(Thread.currentThread().getName() + " 继续执行后续逻辑");
}).start();
}</p>支持屏障动作(Barrier Action)
可在所有线程到达后、释放前,执行一个公共任务(比如汇总数据、记录日志)。通过构造函数传入 Runnable 实现:
CyclicBarrier barrier = new CyclicBarrier(3, () -> {
System.out.println("✅ 所有线程已就位,执行屏障动作(如:触发下一阶段)");
});
注意:该 Runnable 由**最后一个到达的线程执行**,不是额外线程。
处理中断与超时
生产环境建议避免永久阻塞。CyclicBarrier 支持带超时的 await(long timeout, TimeUnit unit),超时未满足条件会抛出 TimeoutException;若线程被中断,则抛出 InterruptedException。此时栅栏进入 broken 状态,需调用 reset() 恢复(或新建实例):
- 调用
isBroken()可检查当前是否损坏 -
reset()会重置栅栏,但正在 await 的线程会收到BrokenBarrierException - 更稳妥做法是捕获异常后重建新 CyclicBarrier(尤其在循环场景中)
典型适用场景
适合需要“分阶段协同”的多线程任务,例如:
- 多线程并行计算一批数据,每轮计算完必须全部汇合,再统一归并/校验/写入
- 模拟“回合制”处理:N 个服务线程各自准备输入 → 同时触发处理 → 同时读取输出
- 压力测试中协调客户端线程,在同一时刻发起请求(配合
Thread.sleep()+await())
不适用于“一次性等待”(用 CountDownLatch 更合适),也不用于线程间传递数据(应配合 BlockingQueue 或 Exchanger)。


















