圖解CyclicBarrier運動員接力賽

圖解遊戲規則


大家都知道運動員短跑接力賽,今天我們並不是講接力賽,我們講「接力協作賽」,需要我們重新定義下遊戲規則:如下圖所示

image.png

現在有運動員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是用來衝破屏障回調的函數。

image.png

 

比較CountDownLatch


CyclicBarrier中文釋義「迴環屏障」,每個執行緒調用await,計數器會減1,如果此時計數器不為0,執行緒會阻塞,如果計數器為0說明需要衝破屏障,會喚醒之前被阻塞的執行緒,並會重置計數器。源碼實現中用到了獨佔鎖和條件隊列控制執行緒的進隊和出隊,CountDownLatch用到的是共享鎖,雖然實現不一樣,底層都是AQS,相對於CountDownLatch來說,CyclicBarrier是它的補充,功能更強大。

 

 

總結


今天我們介紹了CyclicBarrier,整理出來希望能對你有幫助,寫的比不全,同時還有許多需要修正的地方,希望親們加以指正和點評,喜歡的請點贊加關注哦。點關注,不迷路,我是【叫練公眾號,微訊號【jiaolian123abc】邊叫邊練。