cyclicbarrier 是 java 并发包中用于多线程阶段性同步的可重用屏障工具,通过计数器协调线程在屏障点等待并触发合并操作。

CyclicBarrier 是 Java 并发包(java.util.concurrent)中用于协调多个线程在某个“屏障点”同步等待的工具,特别适合实现**多任务分阶段执行、阶段性合并**的场景——比如:多个线程各自完成一部分计算后,必须全部到达某一点才能一起进入下一阶段。
核心机制:等待+触发+重用
CyclicBarrier 的本质是“计数器 + 可选回调”。它内部维护一个计数器,每调用一次 await(),计数减一;当计数归零时:
- 所有等待线程被同时唤醒,继续执行后续逻辑;
- 可指定一个
Runnable作为“屏障动作”,在最后一线程到达时、其他线程被唤醒前执行(常用于汇总、校验、日志等合并操作); - 计数器自动重置,支持重复使用(这也是 “Cyclic” 的由来)。
典型阶段性合并执行结构
以“三阶段处理”为例:每个线程独立执行 Phase 1 → 全部到达屏障 → 合并/检查 → 执行 Phase 2 → 再次同步 → …
- 初始化:
CyclicBarrier barrier = new CyclicBarrier(3, () -> { /* 合并逻辑 */ });(3 表示需 3 个线程参与); - 每个线程在阶段结束处调用
barrier.await(); - 任意线程调用
await()后会阻塞,直到其他线程也调用; - 最后一个线程到达时,屏障动作执行(如收集各线程结果、验证一致性),然后所有线程同时释放,进入下一阶段。
实战示例:4 个线程分批计算后汇总平均值
假设要并行计算 4 组数据的和,再统一算总平均值:
CyclicBarrier barrier = new CyclicBarrier(4, () -> {
double avg = totalSum.get() / 4.0;
System.out.println("所有批次完成,平均值:" + avg);
});
每个线程做自己的计算(如 sum = 随机数累加),存入共享变量(如 AtomicInteger totalSum),然后 barrier.await()。只有第 4 个线程到达时,回调才执行,确保“汇总”发生在全部就绪之后。
注意事项与避坑点
实际使用中需注意:
-
异常处理:
await()可能抛出InterruptedException或BrokenBarrierException(如某线程中断或超时),需捕获并合理响应; -
超时控制:可用
await(long timeout, TimeUnit unit)防止个别线程卡死拖垮整体; -
线程安全:屏障动作和共享数据(如汇总结果)必须保证线程安全,优先用
Atomic*或synchronized; - 不替代 CountDownLatch:CyclicBarrier 是“多方等待彼此”,CountDownLatch 是“一方等待多方”,目的不同,不可混用。
不复杂但容易忽略细节,关键是理解“谁在等、等什么、谁触发合并”,把屏障点当作阶段交接的明确契约。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











