CyclicBarrier是java提供的同步輔助類。
一個同步輔助類,它允許一組線程互相等待,直到到達某個公共屏障點 (common barrier point),才得以繼續執行。阻塞子線程,當阻塞數量到達定義的參與線程數后,才可繼續向下執行。
public class BarrierMain { public static void main(String[] args) { ThreadPoolExecutor executor=new ThreadPoolExecutor(5,5,1, TimeUnit.SECONDS ,new ArrayBlockingQueue<Runnable>(10)){ @Override protected void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); } }; CyclicBarrier cyclicBarrier=new CyclicBarrier(3, new Runnable() { @Override public void run() { System.out.println("=====當前階段已完成"); } }); executor.submit(new BarrierDemo(cyclicBarrier)); executor.submit(new BarrierDemo(cyclicBarrier)); executor.submit(new BarrierDemo(cyclicBarrier)); System.out.println("====主線程執行完畢"); executor.shutdown(); } }
public class BarrierDemo implements Runnable { private final CyclicBarrier barrier; public BarrierDemo(CyclicBarrier barrier) { this.barrier = barrier; } @Override public void run() { try { System.out.println(Thread.currentThread().getName()+"到達現場"); Thread.sleep(5000); //阻塞子線程 barrier.await(); //繼續執行 System.out.println(Thread.currentThread().getName()+"開始表演"); Thread.sleep(5000); barrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }
CountDownLatch與CyclicBarrier:
CountDownLatch是一個同步的輔助類,允許一個或多個線程,等待其他一組線程完成操作,被等待線程(例如主線程)再繼續執行。
CyclicBarrier是一個同步的輔助類,允許一組線程相互之間等待,達到一個共同點,子線程再繼續執行。CyclicBarrier可以被重用,比如有三個線程,執行邏輯到達同步點阻塞,到齊后被喚醒,又再次執行邏輯,到達下一個同步點,到齊后再被喚醒
區別:
- CountDownLatch的計數器只能使用一次。而CyclicBarrier的計數器可以使用reset() 方法重置。所以CyclicBarrier能處理更為復雜的業務場景,比如如果計算發生錯誤,可以重置計數器,並讓線程們重新執行一次
- CyclicBarrier還提供getNumberWaiting(可以獲得CyclicBarrier阻塞的線程數量)、isBroken(用來知道阻塞的線程是否被中斷)等方法。
- CountDownLatch會阻塞主線程,CyclicBarrier不會阻塞主線程,只會阻塞子線程。