Java中的栅栏(CyclicBarrier)
是一种用于协调多个线程并发工作的同步辅助类。与CountDownLatch不同,CyclicBarrier允许一组线程相互等待,直到所有线程都到达一个共同的屏障点(barrier)后,才继续执行。CyclicBarrier的主要特点是可以重复使用,因此适用于需要多个阶段的任务同步。
示例代码:
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierWithActionExample {
public static void main(String[] args) {
int threadCount = 3;
CyclicBarrier barrier = new CyclicBarrier(threadCount, new BarrierAction());
for (int i = 0; i < threadCount; i++) {
new Thread(new TaskWithAction(barrier)).start();
}
}
}
class BarrierAction implements Runnable {
@Override
public void run() {
System.out.println("所有线程都到达屏障点,执行barrierAction。");
}
}
class TaskWithAction implements Runnable {
private final CyclicBarrier barrier;
TaskWithAction(CyclicBarrier barrier) {
this.barrier = barrier;
}
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " 正在执行任务...");
// 模拟任务执行
Thread.sleep((long) (Math.random() * 1000));
System.out.println(Thread.currentThread().getName() + " 到达屏障点。");
barrier.await(); // 等待其他线程到达屏障点
System.out.println(Thread.currentThread().getName() + " 继续执行。");
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
}
在这个例子中,当所有线程都到达屏障点时,会首先执行BarrierAction中的任务,然后再继续执行线程的后续代码。
一个模拟多阶段的任务,每个阶段所有线程都需要同步后才能进入下一个阶段。每个阶段完成后,还会执行一个额外的屏障操作。
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class MultiStageTaskExample {
public static void main(String[] args) {
int threadCount = 4;
int stageCount = 3;
CyclicBarrier barrier = new CyclicBarrier(threadCount, new BarrierAction());
for (int i = 0; i < threadCount; i++) {
new Thread(new Worker(barrier, stageCount)).start();
}
}
}
class Worker implements Runnable {
private final CyclicBarrier barrier;
private final int stageCount;
Worker(CyclicBarrier barrier, int stageCount) {
this.barrier = barrier;
this.stageCount = stageCount;
}
@Override
public void run() {
try {
for (int stage = 1; stage <= stageCount; stage++) {
// 模拟每个阶段的任务
System.out.println(Thread.currentThread().getName() + " 正在执行第 " + stage + " 阶段任务...");
Thread.sleep((long) (Math.random() * 1000)); // 模拟任务执行时间
// 等待其他线程到达屏障点
System.out.println(Thread.currentThread().getName() + " 到达第 " + stage + " 阶段屏障点。");
barrier.await();
}
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
}
class BarrierAction implements Runnable {
@Override
public void run() {
System.out.println("所有线程都已到达屏障点,准备进入下一阶段...");
}
}
跳转到:
CountDownLatch
信号量(Semaphore)