圖解CyclicBarrier運動員接力賽
- 2021 年 3 月 1 日
- 筆記
- AQS, CyclicBarrier, join, 面試
圖解遊戲規則
大家都知道運動員短跑接力賽,今天我們並不是講接力賽,我們講「接力協作賽」,需要我們重新定義下遊戲規則:如下圖所示
現在有運動員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是用來衝破屏障回調的函數。
比較CountDownLatch
CyclicBarrier中文釋義「迴環屏障」,每個線程調用await,計數器會減1,如果此時計數器不為0,線程會阻塞,如果計數器為0說明需要衝破屏障,會喚醒之前被阻塞的線程,並會重置計數器。源碼實現中用到了獨佔鎖和條件隊列控制線程的進隊和出隊,CountDownLatch用到的是共享鎖,雖然實現不一樣,底層都是AQS,相對於CountDownLatch來說,CyclicBarrier是它的補充,功能更強大。
總結
今天我們介紹了CyclicBarrier,整理出來希望能對你有幫助,寫的比不全,同時還有許多需要修正的地方,希望親們加以指正和點評,喜歡的請點贊加關注哦。點關注,不迷路,我是【叫練】公眾號,微信號【jiaolian123abc】邊叫邊練。