溫馨提示×

溫馨提示×

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

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

JUC的CountDownLatch如何實現

發布時間:2021-12-21 10:22:38 來源:億速云 閱讀:197 作者:iii 欄目:大數據

這篇文章主要介紹“JUC的CountDownLatch如何實現”,在日常操作中,相信很多人在JUC的CountDownLatch如何實現問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”JUC的CountDownLatch如何實現”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

CountDownLatch 是一個同步輔助工具,用于阻塞當前一個或多個線程以等待其它線程中的操作完成。在構造 CountDownLatch 對象時,我們需要指定一個非負的 count 值,一般情況下,調用 CountDownLatch#await 方法的線程需要阻塞等待該 count 值變為 0 時才能夠繼續往下執行。

CountDownLatch 實現內幕

CountDownLatch 在實現上同樣依賴于 AQS 組件,在 CountDownLatch 的內部定義了一個 Sync 內部類,該類繼承自 AbstractQueuedSynchronizer,并復用 AQS 的 state 字段以記錄 count 值的變化。CountDownLatch 的核心方法均委托 Sync 進行處理,實現如下:

public class CountDownLatch {

    private final Sync sync;

    public CountDownLatch(int count) {
        if (count < 0) {
            throw new IllegalArgumentException("count < 0");
        }
        this.sync = new Sync(count);
    }

    public void await() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }

    public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
        return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
    }

    public void countDown() {
        sync.releaseShared(1);
    }

    public long getCount() {
        return sync.getCount();
    }

}

下面我們主要分析一下 CountDownLatch#awaitCountDownLatch#countDown 方法的實現。

首先來看一下 CountDownLatch#await 方法,該方法用于阻塞當前線程,直到 count 值變為 0,或者被其它線程中斷。具體實現上,CountDownLatch 直接將請求委托給 AQS 的 AbstractQueuedSynchronizer#acquireSharedInterruptibly 方法進行處理,所以我們下面主要來看一下 CountDownLatch 針對模板方法 AbstractQueuedSynchronizer#tryAcquireShared 的實現,如下:

protected int tryAcquireShared(int acquires) {
    return (getState() == 0) ? 1 : -1;
}

實現上非常簡單,獲取并判定狀態值是否為 0,如果是則說明當前線程獲取資源成功,能夠繼續往下執行,否則說明當前線程獲取資源失敗,需要被添加到同步隊列阻塞等待。CountDownLatch 還為 CountDownLatch#await 方法定義了超時版本 CountDownLatch#await(long, TimeUnit)。

繼續來看一下 CountDownLatch#countDown 方法,該方法用于將 count 值減 1,如果發現 count 值變為 0,則喚醒阻塞等待的線程。具體實現上,CountDownLatch 同樣直接將請求委托給 AQS 的 AbstractQueuedSynchronizer#releaseShared 方法進行處理,所以我們下面主要來看一下 CountDownLatch 針對模板方法 AbstractQueuedSynchronizer#tryReleaseShared 的實現,如下:

protected boolean tryReleaseShared(int releases) {
    // Decrement count; signal when transition to zero
    for (; ; ) {
        // 獲取 state 狀態值
        int c = getState();
        // 如果已經為 0 則說明沒有資源可以釋放,直接返回 false,避免 state 變為負值
        if (c == 0) {
            return false;
        }
        // 資源數減 1
        int nextc = c - 1;
        if (compareAndSetState(c, nextc)) {
            // 如果為 0,則說明資源全部釋放完畢,此時需要喚醒等待的線程
            return nextc == 0;
        }
    }
}

具體實現如代碼注釋,比較簡單。需要注意的一點就是上面步驟中的判 0 操作,剛開始看的時候可能覺得有點多余,但是這一步的主要作用在于保證 state 值不會變為負值。當前 count 值變為 0 時,上述方法會返回 true,接下去 AQS 會執行喚醒之前因為 count 值不為 0 而被打入同步隊列的線程。

到此,關于“JUC的CountDownLatch如何實現”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女