CyclicBarrier-回環(huán)柵欄的使用

CountDownLatch 、 CyclicBarrier 、Semaphore這三個java提供的工具經(jīng)常放在一起做比較,接下來三篇分別使用它們來區(qū)別他們的不同;先說說CyclicBarrier的個人理解,就像一個柵欄一樣,舉行賽跑的時候,所有的人必須全都到白線前等待,然后才開始;這里的白線就是CyclicBarrier,人就是線程;

  1. 構(gòu)造函數(shù)

首先看構(gòu)造函數(shù):

/**
 * @Param parties : 需要計數(shù)的Thread數(shù)量,達到數(shù)量之后柵欄開放
 * @Param barrierAction : 柵欄開放后觸發(fā)的動作 
 */
public CyclicBarrier(int parties, Runnable barrierAction) {
    if (parties <= 0) throw new IllegalArgumentException();
    this.parties = parties;
    this.count = parties;
    this.barrierCommand = barrierAction;
}

// 這是個沒有動作的柵欄
public CyclicBarrier(int parties) {
    this(parties, null);
}
  1. 常用方法

要了解如何用,需要看它的方法, 不分析原理看 public 的方法就行了;這里只看要用到的

// 調(diào)用這個方法,說明到達柵欄,會將到達線程的計數(shù)器加1
public int await() throws InterruptedException, BrokenBarrierException {
    try {
        return dowait(false, 0L);
    } catch (TimeoutException toe) {
        throw new Error(toe); // cannot happen
    }
}

其他還有一些方法,比如:
限制時間的 await
重置柵欄的 reset
獲取等待線程數(shù)的 getNumberWaiting
查看柵欄開放狀態(tài)的 isBroken

這里簡單使用的話使用await方法就夠了;

  1. 簡單案例

我們構(gòu)造一個簡單場景,多線程統(tǒng)計單詞出現(xiàn)的次數(shù), 模擬一堆線程對數(shù)據(jù)操作全部完成之后在輸出結(jié)果


public static void main(String[] args) {
    Map<String, Integer> map = new ConcurrentHashMap<>();
    //創(chuàng)建一個100個計數(shù)的柵欄, 并且柵欄開放之后的方法是打印最終結(jié)果
    CyclicBarrier cyclicBarrier = new CyclicBarrier(100, () -> {
        System.out.println(map.get("test"));
    });
    // 100 線程操作map
    for(int i = 0 ; i < 100; i++) {
        new Thread(() -> {
            try {
                // 這里我們就模擬對 `test` 這個單詞的累加次數(shù)統(tǒng)計 這里使用了map的merge方法,這個方法是接口的默認(rèn)方法,但是在concurrentHashMap中進行了重寫, 可以看到他也是線程安全的; 
                Integer test = map.merge("test", 1, Integer::sum);
                // 每個線程操作完畢,調(diào)用柵欄的await
                cyclicBarrier.await();
                // 當(dāng)柵欄開放這里才會執(zhí)行
                System.out.println("mission result: " + test);
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        }).start();
    }

}

那么我們的CyclicBarrier在這里的作用是什么呢?其實這個在多線程單元測試的時候很常見,應(yīng)為這里是多線程的,在線程start完成之后,直接輸出map.get("test")的值的話,這個時候線程是沒有運行完成的,用了這個回環(huán)柵欄,那么就能讓最后的輸出結(jié)果在線程全部完成之后在進行;
這個效果使用CountDownLatch也可以十分方便的實現(xiàn)

  1. 特點總結(jié)

  2. 可以看見回環(huán)柵欄可以讓執(zhí)行線程全部等待,到所有線程都完成并調(diào)用await的時候, 柵欄開放,所有的線程一起觸發(fā)之后的流程;

  3. 回環(huán)柵欄那么回環(huán)體現(xiàn)在哪里呢?我們可以通過reset方法將它重置,這樣我們就能重新使用它了;關(guān)于reset其中線程的處理可以看reset方法中的處理;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容