CyclicBarrier 一种同步辅助工具,它允许一组线程相互等待以达到共同的障碍点。 CyclicBarriers 在涉及固定大小的线程组的程序中很有用,这些线程组必须偶尔相互等待。 屏障被称为循环的,因为它可以在等待线程被释放后重新使用。
主要方法
构造方法:
public CyclicBarrier(int parties, Runnable barrierAction)
参数:
int parties, 在障碍被触发之前必须调用await的线程数
Runnable barrierAction,当障碍被触发时执行的动作,如果没有动作则为null
void await() 方法:
进入等待的休眠状态。直到发生以下情况之一:
最后一个线程到达;
或者其他一些线程中断当前线程;
或者其他一些线程中断了其他等待线程之一;
或者其他一些线程在等待屏障时超时;
或者其他一些线程在此屏障上调用reset 。
void reset()
将屏障重置为其初始状态。
示例:7 个线程 同时(并行)去找龙珠,当7个都达到时,触发一个动作 "凑齐"
代码示例
public class CyclicBarrierDemo {
public static void main(String[] arr) throws InterruptedException {
// 第一个参数:int parties, 在障碍被触发之前必须调用await的线程数
// 第二个参数:Runnable barrierAction,当障碍被触发时执行的动作,如果没有动作则为null
CyclicBarrier cyclicBarrier = new CyclicBarrier(7, new Runnable() {
@Override
public void run() {
System.out.printf("七颗龙珠已经凑齐,召唤神龙\n");
}
});
// 连续的触发 7 次
for (int i = 0; i < 7; i++) {
new Thread(new Hero(cyclicBarrier)).start();
}
Thread.sleep(5000);
}
public static class Hero implements Runnable {
CyclicBarrier cyclicBarrier ;
public Hero(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
System.out.printf("[%s] 找到一颗龙珠... \n",Thread.currentThread().getName());
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
}
重要成员变量
/ /可以理解为初始化时 需要阻塞的任务个数
private final int parties;
/ /剩余需要等待的任务个数,初始值为parties,直到为0时依次唤醒所有被阻塞的任务线程。
private int count;
/ /每次对“栅栏”的主要成员变量进行变更操作,都应该加锁
private final ReentrantLock lock = new ReentrantLock();
/ /用于阻塞和唤醒任务线程
private final Condition trip = lock.newCondition();
/ /在所有线程被唤醒前,需要执行的一个Runable对应的run方法
private final Runnable barrierCommand;
/ /用于表示“栅栏”当前的状态
private Generation generation = new Generation();
private final ReentrantLock lock = new ReentrantLock();
private final Condition trip = lock.newCondition();
https://blog.csdn.net/chongbin007/article/details/91359728 https://www.jianshu.com/p/043ac5689002