CyclicBarrier可以理解为循环栅栏,栅栏就是一种障碍物,
比如通常在私人宅院的周围就可以围上一圈栅栏,阻止闲杂人等入内。
这里当然就是用来阻止线程继续执行,要求线程在栅栏外等待。
前面的Cyclic意为循环,也就是说这个计数器可以反复使用。
比如,我们将计数器设置为10,那么凑齐第一批10个线程后,计数器就会归零,
接着凑齐下一批10个线程,这就是循环栅栏内在的含义。
CyclicBarrier的使用场景也很丰富。比如,司令下达命令,要求10个士兵一起去
完成一项任务。这时就会要求10个士兵集合报到,接着,一起雄赳赳,气昂昂地去执行任务。
当10个士兵把自己手上的任务都执行完成了,那么司令才对外宣布,任务完成。
CyclicBarrier比CountDownLatch稍微强大一些,
它可以接收一个参数作为barrierAction.
所谓barrierAction就是当计数器一次计数完成后,
系统会执行的动作。
其中parties表示计数总数,也就是参与的线程总数。
public class CyclicBarrierDemo {
public static class Sodier implements Runnable{
private String soldier;
private final CyclicBarrier cyclic;
Sodier(CyclicBarrier cyclic,String soldierName){
this.cyclic = cyclic;
this.soldier = soldierName;
}
public void run() {
try{
cyclic.await();
doWork();
cyclic.await();
} catch (InterruptedException e){
e.printStackTrace();
} catch (BrokenBarrierException e){
e.printStackTrace();
}
}
void doWork(){
try {
Thread.sleep(Math.abs(new Random().nextInt()%10000));
} catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(soldier+":任务完成");
}
}
public static class BarrierRun implements Runnable{
boolean flag;
int N;
public BarrierRun(boolean flag,int N){
this.N = N;
this.flag = flag;
}
public void run() {
if(flag){
System.out.println("司令:[士兵"+ N +"个,任务完成!]");
} else{
System.out.println("司令:[士兵"+ N +"个,集合完毕!]");
flag = true;
}
}
}
public static void main(String[] args) throws InterruptedException{
final int N = 10;
Thread[] allSoldier = new Thread[N];
boolean flag = false;
CyclicBarrier cyclic = new CyclicBarrier(N, new BarrierRun(flag,N));
System.out.println("集合队伍!");
for (int i =0;i< N; ++i){
System.out.println("士兵"+i+"报道!");
allSoldier[i] = new Thread(new Sodier(cyclic,"士兵"+i));
allSoldier[i].start();
}
}
}
创建CyclicBarrier实例,并将计数器设置为10,要求在计数器到达指标时,
执行run()方法。每个士兵线程都会执行run方法。
在第18行cyclic.await()每个士兵都会等待,直到所有的士兵都集合完毕。
集合完毕意味着CyclicBarrier的一次计数完成,当再一次调用CyclicBarrier.await
方法时,会进行下一次计数。doWork();模拟了士兵的任务。
当一个士兵任务执行完,他就会要求CylicBarrier开始下一次计数,
这次计数主要目的是监控是否所有的士兵都已经完成了任务。
一旦任务全部完成。