cyclicbarrier 是 java 并发包中用于多个线程相互等待到达同一屏障点的可重用同步工具,核心机制为计数器减至零时唤醒全部线程并可执行 barrier action。

CyclicBarrier 是 Java 并发包(java.util.concurrent)中用于**多个线程相互等待到达同一屏障点**的同步工具。它与 CountDownLatch 类似但关键不同:CyclicBarrier 可重用,且所有线程都需主动调用 await() 进入等待,一旦达到预定数量,全部线程才同时被唤醒继续执行。
核心机制:计数器 + 条件等待
CyclicBarrier 内部维护一个可重置的计数器(初始值为参与线程总数),每个线程调用 await() 时:
- 将计数器原子减一;
- 若减后为 0(即最后一个线程到达),则触发“屏障开启”:唤醒所有等待线程,并可选择执行一个
Runnable(称为 barrier action); - 否则,当前线程进入条件队列等待(基于
ReentrantLock和Condition实现); - 当屏障开启或超时/中断发生时,所有等待线程被唤醒并从
await()返回(可能抛出异常)。
基本使用示例
假设有 3 个线程协作完成分段任务,必须全部就绪后才统一启动下一阶段:
(注意:实际代码中需处理 InterruptedException 等异常)CyclicBarrier barrier = new CyclicBarrier(3, () -> {
System.out.println("所有线程已就位,开始协同执行!");
});
for (int i = 0; i {
System.out.println(Thread.currentThread().getName() + " 正在准备...");
try {
TimeUnit.SECONDS.sleep(1); // 模拟准备耗时
System.out.println(Thread.currentThread().getName() + " 准备完成,等待其他线程...");
barrier.await(); // 到达屏障点,阻塞直到其他线程也调用 await()
System.out.println(Thread.currentThread().getName() + " 继续执行后续逻辑");
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
关键特性与注意事项
-
可重用性:屏障被触发后,计数器自动重置为初始值,后续可再次调用
await();调用reset()会强制清空等待线程并重置状态(此时正在 await 的线程会收到BrokenBarrierException); -
线程中断敏感:任一线程在
await()中被中断,屏障将被标记为“破损”,其余等待线程也会立即抛出BrokenBarrierException; -
超时控制:支持
await(long timeout, TimeUnit unit),避免无限等待;超时后抛出TimeoutException,同样导致屏障破损; - 非公平性:唤醒顺序不保证与等待顺序一致,取决于底层锁的调度策略。
适用场景
- 多线程并行计算后,统一汇总结果(如分治算法中的归并前等待);
- 模拟并发压力测试(所有线程同时发起请求);
- 多阶段流水线中,确保每阶段所有任务完成后再进入下一阶段。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











