你們都知道運動員短跑接力賽,今天咱們並非講接力賽,咱們講「接力協做賽」,須要咱們從新定義下游戲規則:以下圖所示java
如今有運動員A,B,先定義遊戲規則:賽道目前是300米,每一個運動員在跑完第一個100米時,須要等待其餘運動員跑完第一個100米,好比運動員A先跑完100米,而此時運動員B只跑了95米,那運動員A必需要等待運動員B跑完剩餘的5米,而後再一塊兒接着跑第2個100米,第三個100米,規則也和第1個100米類同,最後咱們能夠得出一個結論,兩個運動員跑完300米賽道,最長鬚要花多少時間。【本案例純屬虛構,爲了講清楚CyclicBarrier】。下面咱們用代碼模擬執行。微信
import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * @author :jiaolian * @date :Created in 2021-03-01 14:56 * @description:迴環屏障測試--接力賽 * @modified By: * 公衆號:叫練 */ public class CyclicBarrierTest { private static final int THREAD_COUNT = 2; private static CyclicBarrier cyclicBarrier = new CyclicBarrier(2,()->{ System.out.println(Thread.currentThread().getName()+"衝破屏障"); }); private static ExecutorService executorService = Executors.newFixedThreadPool(THREAD_COUNT); public static void main(String[] args) { Runnable myTask = new MyTask(); //初始化兩個運動員 for (int i=0 ;i<THREAD_COUNT; i++) { executorService.submit(myTask); } } private static class MyTask implements Runnable { @Override public void run() { try { System.out.println(Thread.currentThread().getName()+"第1個100米"); cyclicBarrier.await(); System.out.println(Thread.currentThread().getName()+"第2個100米"); cyclicBarrier.await(); System.out.println(Thread.currentThread().getName()+"第3個100米"); cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } } }
如上代碼:線程池模擬執行兩個運動員,每一個運動員執行完每一個100米必須等待另外一個運動員,執行結果和咱們設想一致,以下圖所示。其中pool-1-thread-1,pool-1-thread-2分別表示運動員A,運動員B。CyclicBarrier初始化參數中有一個Runnable是用來衝破屏障回調的函數。ide
CyclicBarrier中文釋義「迴環屏障」,每一個線程調用await,計數器會減1,若是此時計數器不爲0,線程會阻塞,若是計數器爲0說明須要衝破屏障,會喚醒以前被阻塞的線程,並會重置計數器。源碼實現中用到了獨佔鎖和條件隊列控制線程的進隊和出隊,CountDownLatch用到的是共享鎖,雖然實現不同,底層都是AQS,相對於CountDownLatch來講,CyclicBarrier是它的補充,功能更強大。函數
今天咱們介紹了CyclicBarrier,整理出來但願能對你有幫助,寫的比不全,同時還有許多須要修正的地方,但願親們加以指正和點評,喜歡的請點贊加關注哦。點關注,不迷路,我是【叫練】公衆號,微信號【jiaolian123abc】邊叫邊練。測試