CyclicBarrier的字面意思是可循環使用的屏障,它的主要做用是,讓一組線程到達一個屏障時被阻塞,知道最後一個線程到達屏障時,屏障纔會打開,全部被屏障攔截的線程纔會繼續運行。java
一、簡介:ide
CyclicBarrier默認的構造方法是CyclicBarrier(int parties),其中參數標識屏障攔截的線程數量,每一個線程調用await方法告訴CyclicBarrier我已經到達了屏障,而後當前線程被阻塞。函數
package com.test; import java.util.concurrent.CyclicBarrier; public class CiclicBarrierTest { static CyclicBarrier c = new CyclicBarrier(2); public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { try { c.await(); } catch (Exception e) { e.printStackTrace(); } System.out.println(1); } }).start(); try { c.await(); } catch (Exception e) { e.printStackTrace(); } System.out.println(2); } }
若是把new CyclicBarrier(2)修改擦new CyclicBarrier(3) 則主線程和子線程會永遠等待,由於沒有第三個線程去執行await方法。既沒有第三個線程到達屏障,因此以前到達屏障的兩個線程都不會繼續執行。spa
CyclicBarrier還提供一個更高級的構造函數,CyclicBarrier(int parties, Runnable barrier-Action)用於在線程到達屏障時,優先執行barrierAction,方便處理更復雜的業務場景:線程
package com.test; import java.util.concurrent.CyclicBarrier; public class CiclicBarrierTest { static CyclicBarrier c = new CyclicBarrier(2, new A()); public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { try { c.await(); } catch (Exception e) { e.printStackTrace(); } System.out.println(1); } }).start(); try { c.await(); } catch (Exception e) { e.printStackTrace(); } System.out.println(2); } public static class A implements Runnable { @Override public void run() { System.out.println(3); } } } // 結果 3 1 2
CyclicBarrier和CountDownLatch的區別:code
CountDownLatch的計數器只能使用一次,而CyclicBarrier的計數器能夠使用reset()方法重置。因此CyclicBarrier能處理更爲複雜的業務場景。blog
CyclicBarrier還提供其餘有用的方法,好比getNumberWaiting方法能夠得到被阻塞的線程數量. isBroken()方法用來了解阻塞的線程是否被中斷。get