【Java併發】CountDownLatch

ReentrantLock爲獨佔鎖,也即排他鎖,同一時刻只能有一個線程持有鎖。現在來看幾種共享鎖。

CountDownLatch

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

private final Sync sync;

private static final class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = 4982264981922014374L;

        Sync(int count) {
            //設置資源總數
            setState(count);
        }

        int getCount() {
            return getState();
        }

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

        protected boolean tryReleaseShared(int releases) {
            // Decrement count; signal when transition to zero
            for (;;) {
                //1、獲取當前資源數
                int c = getState();
                if (c == 0)
                    return false;
                //2、釋放一個資源
                int nextc = c-1;
                //3、CAS更新資源數
                if (compareAndSetState(c, nextc))
                    return nextc == 0;
            }
        }
    }

生成CountDownLatch時需要傳入資源總數,代表所有線程總共享有這麼多資源。Sync爲一個實現了AQS的內部類,代理CountDownLatch的獲取和釋放操作。

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

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

線程調用countDown時,最終調用Sync中的tryReleaseShared,將總資源減1。調用await時,最終調用Sync中tryAcquireShared,看資源是否全部釋放完。

需要所有線程等待某個條件完成後,才執行某個動作時,可以使用CountDownLatch。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章