CyclicBarrier使用

CyclicBarrier循環(huán)屏障(障礙),同樣都是jdk線程并發(fā)包下的java.util.concurrent,底層使用ReentrantLock可重入鎖,共享資源重復加鎖,該線程獲取鎖不被阻塞。
使用場景:約好4個人一起打麻將,如果是三缺一就無法進行,三個人需要等待1人,四個人達到麻將館即可開戰(zhàn)。
或者處理間斷,反復請求時,避免一條條的處理,定義規(guī)則滿足10次提交一次業(yè)務流,當不滿足10次,一直阻塞等待。

/**
 *  CyclicBarrier 循環(huán)屏障
 *  jdk:"一種同步幫助,允許一組線程等待所有線程,互相達到一個共同的障礙點",大白話講:滿足n個線程數(shù)量,才能訪問后續(xù)動作,不滿足就一直等待。
 */
public class CyclicBarrierTest {

    public static final Logger logger = LoggerFactory.getLogger(CyclicBarrierTest.class);

    public static void main(String[] args) {

        /**
         * Creates a new {@code CyclicBarrier} that will trip when the
         * given number of parties (threads) are waiting upon it, and
         * does not perform a predefined action when the barrier is tripped.
         *
         * @param parties the number of threads that must invoke {@link #await}
         *        before the barrier is tripped
         * @throws IllegalArgumentException if {@code parties} is less than 1
         */

        //定義5個循環(huán)障礙,5個線程執(zhí)行完后,會解除阻塞,計數(shù)清零。然后循環(huán)重復此規(guī)則
        CyclicBarrier cyclicBarrier = new CyclicBarrier(5);

        //定義一個緩存線程池,如果有空閑的線程進行回收,否則創(chuàng)建新的線程
        ExecutorService executors = Executors.newCachedThreadPool();

        //這里可以模擬不同的請求數(shù)來驗證,第一次可以循環(huán)5次,第二次循環(huán)6次,第三次循環(huán)10次,來觀察不同之處
        //循環(huán)5次,剛好一組任務完成。
        //循環(huán)6次,只能滿足第一組任務,第二組任務將一直等待,阻塞任務。
        //循環(huán)十次,兩組任務都可以完成。
        for (int i = 0; i < 10; i++) {
            executors.execute(() -> {
                logger.info(Thread.currentThread().getName() + "進入考場");
                try {
                    //dowait方法ReentrantLock  可重入鎖
                    cyclicBarrier.await();

                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
                logger.info(Thread.currentThread().getName() + "開始考試...");
            });
        }

        executors.shutdown();
    }
}

日中輸出:

18:05:19.283 [pool-1-thread-3] INFO com.test.tenant.CyclicBarrierTest - pool-1-thread-3進入考場
18:05:19.283 [pool-1-thread-4] INFO com.test.tenant.CyclicBarrierTest - pool-1-thread-4進入考場
18:05:19.283 [pool-1-thread-5] INFO com.test.tenant.CyclicBarrierTest - pool-1-thread-5進入考場
18:05:19.283 [pool-1-thread-1] INFO com.test.tenant.CyclicBarrierTest - pool-1-thread-1進入考場
18:05:19.283 [pool-1-thread-2] INFO com.test.tenant.CyclicBarrierTest - pool-1-thread-2進入考場
18:05:19.286 [pool-1-thread-3] INFO com.test.tenant.CyclicBarrierTest - pool-1-thread-3開始考試...
18:05:19.286 [pool-1-thread-5] INFO com.test.tenant.CyclicBarrierTest - pool-1-thread-5開始考試...
18:05:19.286 [pool-1-thread-4] INFO com.test.tenant.CyclicBarrierTest - pool-1-thread-4開始考試...
18:05:19.286 [pool-1-thread-2] INFO com.test.tenant.CyclicBarrierTest - pool-1-thread-2開始考試...
18:05:19.286 [pool-1-thread-1] INFO com.test.tenant.CyclicBarrierTest - pool-1-thread-1開始考試...

CyclicBarrier 和CountDownLatch區(qū)別:

阻塞區(qū)別:
CountDownLatch某一個或多個線程 ,等待其他線程執(zhí)行完成之后,才能繼續(xù)執(zhí)行。父線程等待子線程執(zhí)行完成,才能繼續(xù)執(zhí)行。
CyclicBarrier 一組線程互相等待,任何一個未執(zhí)行完成,其他線程都需要等待。10個線程,全部完成,才能執(zhí)行后續(xù)動作。

使用次數(shù)區(qū)別:
CountDownLatch倒計時門閂,每執(zhí)行一次都是遞減1,await等于0時,結束阻塞,不可重復使用
CyclicBarrier循環(huán)屏障,每執(zhí)行一次都是遞加1,barrier釋放完后,可繼續(xù)使用,重復循環(huán)使用。

鎖區(qū)別
CountDownLatch 內(nèi)部使用 Sync AQS 狀態(tài)來控制,volatile可見性控制線程間變量共享
CyclicBarrier內(nèi)部使用ReentrantLock可重入鎖

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

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