CountDownLatch源码分析

CountDownLatch、Semaphore(信号量)和ReentrantReadWriteLock.ReadLock(读锁)都采用AbstractOwnableSynchronizer共享排队的方式实现。

关于AbstractQueuedSynchronizer中的独占锁和共享锁,请参考ReentrantLock(http://www.cnblogs.com/bjorney/p/8040085.html)和ReentrantReadWriteLock(http://www.cnblogs.com/bjorney/p/8064268.html)

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排队等锁的节点(线程)
        }
    }
}
posted @ 2018-01-22 15:28  Uncle_Bjorney  阅读(112)  评论(0编辑  收藏  举报