CyclicBarrier是一个可重复使用的同步工具,用于让一组线程互相等待直至全部到达共同屏障点后同时继续执行,适用于分阶段任务或并行计算场景。

在Java多线程编程中,CyclicBarrier 是一个同步工具,用于让一组线程互相等待,直到所有线程都到达某个公共的屏障点(barrier point),然后再继续执行。它特别适合用于并行计算、分阶段任务等场景。与 CountDownLatch 不同,CyclicBarrier 可以重复使用,一旦被重置,就能再次投入使用。
什么是CyclicBarrier?
CyclicBarrier 的构造函数需要指定参与的线程数量。当这些线程中的每一个都调用 await() 方法时,它们会被阻塞,直到最后一个线程也调用 await(),此时所有线程同时被释放,并可选择性地执行一个预定义的“结束动作”(barrier action)。
关键特性:
- 支持重复使用(循环)
- 所有线程必须到达屏障点才能继续
- 可选的 barrier action 在所有线程到达后执行一次
基本使用方法
下面是一个简单的例子,展示如何使用 CyclicBarrier 让5个线程同时开始工作:
立即学习“Java免费学习笔记(深入)”;
睿拓智能网站系统-睿拓企业网站系统1.2免费版软件大小:6M运行环境:asp+access本版本是永州睿拓信息企业网站管理系统包括了企业网站常用的各种功能,带完整的后台管理系统,本程序无任何功能限制下载即可使用,具体功能如下。1.网站首页2.会员注册3.新闻文章模块4.产品图片展示模块5.人才招聘模块6.在线留言模块7.问卷调查模块8.联系我们模块9.在线QQ客服系统10.网站流量统计系统11.后
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierExample {
public static void main(String[] args) {
int threadCount = 5;
CyclicBarrier barrier = new CyclicBarrier(threadCount, () -> {
System.out.println("所有线程已就位,比赛开始!");
});
for (int i = 0; i < threadCount; i++) {
new Thread(new Worker(barrier)).start();
}
}
static class Worker implements Runnable {
private final CyclicBarrier barrier;
Worker(CyclicBarrier barrier) {
this.barrier = barrier;
}
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " 准备就绪...");
barrier.await(); // 等待其他线程
System.out.println(Thread.currentThread().getName() + " 开始执行任务。");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
输出可能如下:
Thread-0 准备就绪...Thread-1 准备就绪...
Thread-2 准备就绪...
Thread-3 准备就绪...
Thread-4 准备就绪...
所有线程已就位,比赛开始!
Thread-0 开始执行任务。
Thread-1 开始执行任务。
Thread-2 开始执行任务。
Thread-3 开始执行任务。
Thread-4 开始执行任务。
实际应用场景
CyclicBarrier 常用于以下情况:
- 多线程计算分段任务:比如将一个大数组分成几段,多个线程并行处理,每完成一轮就同步一次再进入下一阶段。
- 模拟并发测试:确保多个线程在同一时刻发起请求,测试系统并发能力。
- 游戏或动画同步启动:多个角色或线程需同时开始行动。
示例:分阶段任务处理
CyclicBarrier stageBarrier = new CyclicBarrier(3);
Runnable task = () -> {
try {
System.out.println("第一阶段:" + Thread.currentThread().getName());
// 第一阶段工作
Thread.sleep(1000);
stageBarrier.await();
System.out.println("第二阶段:" + Thread.currentThread().getName());
// 第二阶段工作
Thread.sleep(1000);
stageBarrier.await();
System.out.println("第三阶段:" + Thread.currentThread().getName());
} catch (Exception e) {
e.printStackTrace();
}
};
for (int i = 0; i < 3; i++) {
new Thread(task).start();
}
注意事项
使用 CyclicBarrier 时要注意几点:
- 如果某个线程在 await() 时被中断或超时,其他所有等待的线程会收到 BrokenBarrierException,表示屏障已被破坏。
- 可以使用 reset() 方法手动重置屏障,未完成的线程会抛出异常。
- 避免死锁:确保所有参与线程最终都会调用 await(),否则会一直等待。









