溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java中的CyclicBarrier源碼分析

發(fā)布時間:2022-04-14 10:46:58 來源:億速云 閱讀:138 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹了Java中的CyclicBarrier源碼分析的相關(guān)知識,內(nèi)容詳細(xì)易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇Java中的CyclicBarrier源碼分析文章都會有所收獲,下面我們一起來看看吧。

    CyclicBarrier簡介

    對于CountDownLatch,其他線程為游戲玩家,比如英雄聯(lián)盟,主線程為控制游戲開始的線程。在所有的玩家都準(zhǔn)備好之前,主線程是處于等待狀態(tài)的,也就是游戲不能開始。當(dāng)所有的玩家準(zhǔn)備好之后,下一步的動作實(shí)施者為主線程,即開始游戲。

    對于CyclicBarrier,假設(shè)有一家公司要全體員工進(jìn)行團(tuán)建活動,活動內(nèi)容為翻越三個障礙物,每一個人翻越障礙物所用的時間是不一樣的。但是公司要求所有人在翻越當(dāng)前障礙物之后再開始翻越下一個障礙物,也就是所有人翻越第一個障礙物之后,才開始翻越第二個,以此類推。類比地,每一個員工都是一個“其他線程”。當(dāng)所有人都翻越的所有的障礙物之后,程序才結(jié)束。而主線程可能早就結(jié)束了,這里我們不用管主線程。

    CyclicBarrier源碼分析

    類的繼承關(guān)系

    CyclicBarrier沒有顯示繼承哪個父類或者實(shí)現(xiàn)哪個父接口, 所有AQS和重入鎖不是通過繼承實(shí)現(xiàn)的,而是通過組合實(shí)現(xiàn)的。

    public class CyclicBarrier {}
    ```  
    
    ### 類的內(nèi)部類
    
    CyclicBarrier類存在一個內(nèi)部類Generation,每一次使用的CycBarrier可以當(dāng)成Generation的實(shí)例,其源代碼如下
    
    ```java
    private static class Generation {
    boolean broken = false;
    }

    說明: Generation類有一個屬性broken,用來表示當(dāng)前屏障是否被損壞。

    類的屬性

    public class CyclicBarrier {
    
    /** The lock for guarding barrier entry */
    // 可重入鎖
    private final ReentrantLock lock = new ReentrantLock();
    /** Condition to wait on until tripped */
    // 條件隊(duì)列
    private final Condition trip = lock.newCondition();
    /** The number of parties */
    // 參與的線程數(shù)量
    private final int parties;
    /* The command to run when tripped */
    // 由最后一個進(jìn)入 barrier 的線程執(zhí)行的操作
    private final Runnable barrierCommand;
    /** The current generation */
    // 當(dāng)前代
    private Generation generation = new Generation();
    // 正在等待進(jìn)入屏障的線程數(shù)量
    private int count;
    }

    說明: 該屬性有一個為ReentrantLock對象,有一個為Condition對象,而Condition對象又是基于AQS的,所以,歸根到底,底層還是由AQS提供支持。

    類的構(gòu)造函數(shù)

    CyclicBarrier(int, Runnable)型構(gòu)造函數(shù)

    public CyclicBarrier(int parties, Runnable barrierAction) {
    // 參與的線程數(shù)量小于等于0,拋出異常
    if (parties <= 0) throw new IllegalArgumentException();
    // 設(shè)置parties
    this.parties = parties;
    // 設(shè)置count
    this.count = parties;
    // 設(shè)置barrierCommand
    this.barrierCommand = barrierAction;
    }

    說明: 該構(gòu)造函數(shù)可以指定關(guān)聯(lián)該CyclicBarrier的線程數(shù)量,并且可以指定在所有線程都進(jìn)入屏障后的執(zhí)行動作,該執(zhí)行動作由最后一個進(jìn)行屏障的線程執(zhí)行。

    CyclicBarrier(int)型構(gòu)造函數(shù)

    public CyclicBarrier(int parties) {
    // 調(diào)用含有兩個參數(shù)的構(gòu)造函數(shù)
    this(parties, null);
    }

    說明: 該構(gòu)造函數(shù)僅僅執(zhí)行了關(guān)聯(lián)該CyclicBarrier的線程數(shù)量,沒有設(shè)置執(zhí)行動作。

    核心函數(shù) - dowait函數(shù)

    此函數(shù)為CyclicBarrier類的核心函數(shù),CyclicBarrier類對外提供的await函數(shù)在底層都是調(diào)用該了doawait函數(shù),

    其源代碼如下:

    private int dowait(boolean timed, long nanos)
    throws InterruptedException, BrokenBarrierException,
    TimeoutException {
    // 保存當(dāng)前鎖
    final ReentrantLock lock = this.lock;
    // 鎖定
    lock.lock();
    try {
    // 保存當(dāng)前代
    final Generation g = generation;
    
    if (g.broken) // 屏障被破壞,拋出異常
    throw new BrokenBarrierException();
    
    if (Thread.interrupted()) { // 線程被中斷
    // 損壞當(dāng)前屏障,并且喚醒所有的線程,只有擁有鎖的時候才會調(diào)用
    breakBarrier();
    // 拋出異常
    throw new InterruptedException();
    }
    
    // 減少正在等待進(jìn)入屏障的線程數(shù)量
    int index = --count;
    if (index == 0) { // 正在等待進(jìn)入屏障的線程數(shù)量為0,所有線程都已經(jīng)進(jìn)入
    // 運(yùn)行的動作標(biāo)識
    boolean ranAction = false;
    try {
    // 保存運(yùn)行動作
    final Runnable command = barrierCommand;
    if (command != null) // 動作不為空
    // 運(yùn)行
    command.run();
    // 設(shè)置ranAction狀態(tài)
    ranAction = true;
    // 進(jìn)入下一代
    nextGeneration();
    return 0;
    } finally {
    if (!ranAction) // 沒有運(yùn)行的動作
    // 損壞當(dāng)前屏障
    breakBarrier();
    }
    }
    
    // loop until tripped, broken, interrupted, or timed out
    // 無限循環(huán)
    for (;;) {
    try {
    if (!timed) // 沒有設(shè)置等待時間
    // 等待
    trip.await();
    else if (nanos > 0L) // 設(shè)置了等待時間,并且等待時間大于0
    // 等待指定時長
    nanos = trip.awaitNanos(nanos);
    } catch (InterruptedException ie) {
    if (g == generation && ! g.broken) { // 等于當(dāng)前代并且屏障沒有被損壞
    // 損壞當(dāng)前屏障
    breakBarrier();
    // 拋出異常
    throw ie;
    } else { // 不等于當(dāng)前帶后者是屏障被損壞
    // We're about to finish waiting even if we had not
    // been interrupted, so this interrupt is deemed to
    // "belong" to subsequent execution.
    // 中斷當(dāng)前線程
    Thread.currentThread().interrupt();
    }
    }
    
    if (g.broken) // 屏障被損壞,拋出異常
    throw new BrokenBarrierException();
    
    if (g != generation) // 不等于當(dāng)前代
    // 返回索引
    return index;
    
    if (timed && nanos <= 0L) { // 設(shè)置了等待時間,并且等待時間小于0
    // 損壞屏障
    breakBarrier();
    // 拋出異常
    throw new TimeoutException();
    }
    }
    } finally {
    // 釋放鎖
    lock.unlock();
    }
    }

    核心函數(shù) - nextGeneration函數(shù)

    此函數(shù)在所有線程進(jìn)入屏障后會被調(diào)用,即生成下一個版本,所有線程又可以重新進(jìn)入到屏障中,

    其源代碼如下:

    private void nextGeneration() {
    // signal completion of last generation
    // 喚醒所有線程
    trip.signalAll();
    // set up next generation
    // 恢復(fù)正在等待進(jìn)入屏障的線程數(shù)量
    count = parties;
    // 新生一代
    generation = new Generation();
    }

    在此函數(shù)中會調(diào)用AQS的signalAll方法,即喚醒所有等待線程。如果所有的線程都在等待此條件,則喚醒所有線程。

    其源代碼如:

    public final void signalAll() {
    if (!isHeldExclusively()) // 不被當(dāng)前線程獨(dú)占,拋出異常
    throw new IllegalMonitorStateException();
    // 保存condition隊(duì)列頭節(jié)點(diǎn)
    Node first = firstWaiter;
    if (first != null) // 頭節(jié)點(diǎn)不為空
    // 喚醒所有等待線程
    doSignalAll(first);
    }

    關(guān)于“Java中的CyclicBarrier源碼分析”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“Java中的CyclicBarrier源碼分析”知識都有一定的了解,大家如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道。

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI