CountDownLatch源碼分析

CountDownLatch、Semaphore(信號量)和ReentrantReadWriteLock.ReadLock(讀鎖)都採用AbstractOwnableSynchronizer共享排隊的方式實現。html

關於AbstractQueuedSynchronizer中的獨佔鎖和共享鎖,請參考ReentrantLock(http://www.cnblogs.com/bjorney/p/8040085.html)和ReentrantReadWriteLock(http://www.cnblogs.com/bjorney/p/8064268.html)ui

1. CountDownLatch

public class CountDownLatch {
    private final Sync sync;

    public CountDownLatch(int count) {
        if (count < 0) throw new IllegalArgumentException("count < 0");
        this.sync = new Sync(count); // sync的鎖狀態(鎖計數)state = count
    }

    public void await() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);  // 參數1並未使用
    }

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

    public void countDown() {
        sync.releaseShared(1); // sync的鎖狀態(鎖計數)state--,見Sync.tryReleaseShared
    }

    ... ...

}

2. CountDownLatch.sync

private static final class Sync extends AbstractQueuedSynchronizer {
    Sync(int count) {
        setState(count); // sync的鎖狀態(鎖計數)state = count
    }

    protected int tryAcquireShared(int acquires) {
        return (getState() == 0) ? 1 : -1; // 若state > 0(嘗試取鎖失敗),則當前線程進入SyncQueue排隊等鎖
    }

    protected boolean tryReleaseShared(int releases) {
        for (;;) {
            // CAS(state)失敗將回到此處
            int c = getState();                 /*記錄state*/
            if (c == 0)
                return false;
            int nextc = c - 1;
            if (compareAndSetState(c, nextc))   /*CAS設置state -= 1*/ 
                return nextc == 0; // 若state爲0(嘗試釋放鎖成功),則喚醒全部在SyncQueue排隊等鎖的節點(線程)
        }
    }
}
相關文章
相關標籤/搜索