1. 介绍
它可以实现线程间
的计数等待,并且可以循环计数。每凑齐一批后又可以继续重新计数。
2. 构造函数
public CyclicBarrier(int parties);
public CyclicBarrier(int parties, Runnable barrierAction);
3. 示例
集合完毕会执行回调方法,任务完成也会再执行一个回调方法。
public class Test01 {
public static class Soldier implements Runnable{
private String soldier;
private CyclicBarrier cyclicBarrier;
public Soldier(CyclicBarrier cyclicBarrier, String soldierName){
this.cyclicBarrier = cyclicBarrier;
this.soldier = soldierName;
}
@Override
public void run() {
try {
cyclicBarrier.await();
doWork();
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
public void doWork() throws InterruptedException {
Thread.sleep(Math.abs(new Random().nextInt(5))*1000);
System.out.println(soldier + "任务完成");
}
}
public static class BarrierRun implements Runnable{
private Boolean flag;
private int N;
public BarrierRun(Boolean flag, int N){
this.flag = false;
this.N = N;
}
@Override
public void run() {
if(flag){
System.out.println("士兵"+N+"个任务完成");
}else {
System.out.println("士兵"+N+"个集合完毕");
flag = true;
}
}
}
@Test
public void test01() throws Exception{
final int N = 10;
Thread[] allSoldier = new Thread[N];
boolean flag = false;
CyclicBarrier cyclicBarrier = new CyclicBarrier(N, new BarrierRun(flag, N));
for (int i = 0; i < N; i++) {
System.out.println("士兵"+i+"报道");
allSoldier[i] = new Thread(new Soldier(cyclicBarrier, "士兵"+i));
allSoldier[i].start();
}
Thread.sleep(8000);
}
}
4. 异常说明
CyclicBarrier.await()方法会抛出两个异常,一个是InterruptedException
,也就是等待过程中,线程被中断。另一个是BrokenBarrierException
,一旦遇到这个异常表明CyclicBarrier已经破坏了,无法等待线程到齐了。比如:如果一个线程收到InterruptedException
异常,那么其它等待的线程都是报BrokenBarrierException
异常,这样就避免了其它9个线程进行无畏的等待。
实时内容请关注微信公众号,公众号与博客同时更新:程序员星星