CyclicBarrier
设置一个屏障点,当所有参与线程(指定的线程数量)都到达屏障时,屏障会打开,所有线程继续执行。CyclicBarrier
可以被重复使用,因此称为“循环的”屏障(cyclic barrier)。每当所有线程都到达屏障点并继续执行后,屏障会被重置,准备下一次使用。CyclicBarrier
提供了两种构造方法:
CyclicBarrier(int parties)
:创建一个新的 CyclicBarrier
,它将拦截指定数量(parties
)的线程,直到这些线程全部到达屏障点。CyclicBarrier(int parties, Runnable barrierAction)
:创建一个新的 CyclicBarrier
,当所有线程到达屏障点时,先执行一个指定的 barrierAction
,然后释放所有线程。以下是一个使用 CyclicBarrier
的简单示例,模拟多个线程同时处理不同部分的数据,当所有线程都处理完毕时,进行汇总处理。
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierExample {
public static void main(String[] args) {
int numberOfThreads = 3;
// 创建 CyclicBarrier,指定屏障点线程数量和一个在屏障开启时执行的任务
CyclicBarrier barrier = new CyclicBarrier(numberOfThreads, () -> {
System.out.println("All tasks completed. Proceeding to the next step.");
});
// 创建并启动多个线程
for (int i = 0; i < numberOfThreads; i++) {
new Thread(new Task(barrier)).start();
}
}
static class Task implements Runnable {
private CyclicBarrier barrier;
public Task(CyclicBarrier barrier) {
this.barrier = barrier;
}
@Override
public void run() {
try {
// 模拟任务处理
System.out.println(Thread.currentThread().getName() + " is processing.");
Thread.sleep((int) (Math.random() * 1000));
// 到达屏障点,等待其他线程
System.out.println(Thread.currentThread().getName() + " has reached the barrier.");
barrier.await();
// 继续执行
System.out.println(Thread.currentThread().getName() + " is continuing.");
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
}
}
解释:
Task
任务。barrier.await()
,表示到达屏障点并等待其他线程。await()
后,CyclicBarrier
打开屏障,所有线程继续执行,并打印“is continuing”。barrierAction
:在屏障打开前,执行构造 CyclicBarrier
时指定的任务(打印“All tasks completed. Proceeding to the next step.”)。CyclicBarrier
适合用于以下场景:
CyclicBarrier
可以用于协调线程同步。CyclicBarrier
将大任务分成多个子任务,多个线程并行执行,最后汇总结果。CyclicBarrier
控制多线程操作,使它们同步执行某些步骤。CyclicBarrier
与 CountDownLatch
都用于线程之间的协调,但它们有一些不同之处:
CyclicBarrier
可以被重置并循环使用,而 CountDownLatch
只能使用一次。CyclicBarrier
控制的是线程到达屏障点的数量,而 CountDownLatch
控制的是倒计数的次数。CyclicBarrier
是一种用于协调多个线程同时到达一个屏障点的工具。它的主要特点是可以重复使用,适合用于多线程分阶段处理任务的场景。在 Java 中,通过 CyclicBarrier
,可以轻松实现多个线程在特定点同步,从而协调它们的执行顺序。