CyclicBarrier是Java并发包中一个非常有用的同步工具类,属于java.util.concurrent包。它允许一组线程互相等待,直到所有线程都到达一个公共的屏障点。CyclicBarrier在并发编程中常用于需要多个线程共同完成某个工作时的场景。
CyclicBarrier的基本原理
CyclicBarrier的构造函数需要指明需要等待的线程数量。例如,如果设置为5,则只有当5个线程都调用了await方法,才会继续执行后面的代码。当所有线程都到达屏障点以后,CyclicBarrier会被重置,可以再次使用,这也是CyclicBarrier与其他同步工具的一个不同点。
CyclicBarrier的工作原理可以简单总结为: 1. 每个线程在执行到达屏障的方法时,都会在CyclicBarrier内部进行计数。 2. 当计数达到预设值时,所有等待的线程被唤醒,继续执行。 3. 如果某个线程在等待过程中中断,CyclicBarrier会抛出BrokenBarrierException异常,其他线程也会被阻塞。
CyclicBarrier的源码解析
CyclicBarrier的核心类由多个内部类组成,其中最重要的字段是count
和parties
。其中count
用于记录当前到达屏障的线程数量,而parties
则表示需要等待的线程总数。
CyclicBarrier的关键方法如下:
- await():调用该方法的线程会被阻塞直到
count
达到parties
。 - reset():重置CyclicBarrier的状态,允许其重新使用。
- getParties():获取设置的等待线程数量。
以下是CyclicBarrier的部分简化源码(主要结构):
public class CyclicBarrier {
private final int parties; // 等待的线程数量
private int count; // 当前到达的线程数量
public CyclicBarrier(int parties) {
if (parties <= 0) throw new IllegalArgumentException();
this.parties = parties;
this.count = parties; // 初始化计数
}
public synchronized int await() throws InterruptedException, BrokenBarrierException {
// 增加到达计数
count--;
if (count == 0) {
count = parties; // 重置计数
notifyAll(); // 唤醒所有等待线程
return 0; // 返回结果
}
// 等待其他线程的到达
while (count > 0) {
wait();
}
return 0;
}
}
CyclicBarrier的示例
下面是一个使用CyclicBarrier的简单示例,我们将使用4个线程并行任务,所有线程在一个点上等待,直到都准备好再一起执行某个操作。
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierExample {
private static final int NUMBER_OF_THREADS = 4;
public static void main(String[] args) {
// 创建一个CyclicBarrier对象,设定等待4个线程
CyclicBarrier barrier = new CyclicBarrier(NUMBER_OF_THREADS, new Runnable() {
public void run() {
System.out.println("所有线程已经到达,开始执行主操作...");
}
});
for (int i = 0; i < NUMBER_OF_THREADS; i++) {
final int threadNumber = i;
new Thread(() -> {
try {
System.out.println("线程 " + threadNumber + " 正在准备...");
// 模拟一些准备工作
Thread.sleep((long) (Math.random() * 1000));
System.out.println("线程 " + threadNumber + " 准备好了,等待其他线程...");
barrier.await(); // 等待其他线程到达
System.out.println("线程 " + threadNumber + " 开始执行!");
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}
}
总结
CyclicBarrier在多线程编程中扮演着重要角色,可以提高程序的效率和可读性。它使得多个线程能够在同一时刻执行某项操作,尤其适合需要协作的任务。通过以上的源码解析和示例代码,相信您对CyclicBarrier有了更深入的理解。