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個線程進行無畏的等待。