1.簡介
可循環利用的屏障。
它允許一組線程互相等待,直到到達某個公共屏障點 (common barrier point)。在涉及一組固定大小的線程的程序中,這些線程必須不時地互相等待,此時 CyclicBarrier 很有用。因爲該 barrier 在釋放等待線程後可以重用,所以稱它爲循環 的 barrier。
作用:會讓所有線程都等待完成後纔會繼續下一步行動。
2.使用場景
需要所有的子任務都完成時,才執行主任務,這個時候就可以選擇使用CyclicBarrier。
3.主要方法
public int await() throws InterruptedException, BrokenBarrierException
public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException
解析:
線程調用 await() 表示自己已經到達柵欄
BrokenBarrierException 表示柵欄已經被破壞,破壞的原因可能是其中一個線程 await() 時被中斷或者超時
4.例子
所有的線程都準備好了,再啓動,啓動都完成第一節點後,再次啓動,完成第二節點的任務。
public class CyclicBarrierDemo implements Runnable {
private CyclicBarrier cyclicBarrier;
public CyclicBarrierDemo(CyclicBarrier cyclicBarrier){
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
System.out.println("當前線程:" + Thread.currentThread().getName() + "準備");
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("當前線程:" + Thread.currentThread().getName() + "第一節點啓動");
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("當前線程:" + Thread.currentThread().getName() + "第2節點啓動");
}
public static void main(String[] args) throws InterruptedException {
CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
ExecutorService executor = Executors.newFixedThreadPool(3);
executor.submit(new CyclicBarrierDemo(cyclicBarrier));
executor.submit(new CyclicBarrierDemo(cyclicBarrier));
executor.submit(new CyclicBarrierDemo(cyclicBarrier));
executor.shutdown();
}
}