CountDownLatch源码分析

Posted Uncle_Bjorney

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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排队等锁的节点(线程)
        }
    }
}

以上是关于CountDownLatch源码分析的主要内容,如果未能解决你的问题,请参考以下文章

CountDownLatch源码分析

AQS源码探究_07 CountDownLatch源码分析

AQS源码探究_07 CountDownLatch源码分析

多线程等待所有子线程执行完使用总结——CountDownLatch使用和源码初步分析

JDK源码分析深入源码分析CountDownLatch

CountDownLatch源码分析