CountDownLatch

CountDownLatch

类图

CountDownLatch本身没有任何父类或是实现任何接口,只含有一个内部类Sync.

CountDownLatch

await

CountDownLatch.await:

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

AbstractQueuedSynchronizer.acquireSharedInterruptibly:

1public final void acquireSharedInterruptibly(int arg) throws InterruptedException {
2    if (Thread.interrupted()) throw new InterruptedException();
3    if (tryAcquireShared(arg) < 0)
4        doAcquireSharedInterruptibly(arg);
5}

这个套路已经见过很多次了,关键的逻辑便是Sync.tryAcquireShared:

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

可以看出,await成功的条件是当前读锁(共享锁)不再被其它线程持有

countDown

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

AbstractQueuedSynchronizer.releaseShared:

1public final boolean releaseShared(int arg) {
2    if (tryReleaseShared(arg)) {
3        doReleaseShared();
4        return true;
5    }
6    return false;
7}

还是一样的套路,Sync.tryReleaseShared:

 1protected boolean tryReleaseShared(int releases) {
 2    // Decrement count; signal when transition to zero
 3    for (;;) {
 4        int c = getState();
 5        if (c == 0)
 6            return false;
 7        int nextc = c-1;
 8        if (compareAndSetState(c, nextc))
 9            return nextc == 0;
10    }
11}

可以看出,countDown真正的逻辑其实是将读锁的持有数减一。

构造器

1public CountDownLatch(int count) {
2    this.sync = new Sync(count);
3}

Sync构造器:

1Sync(int count) {
2    setState(count);
3}

关键便在这里了: AbstractQueuedSynchronizer的初始状态(即锁的持有数)不为零

总结

CountDownLatch的原理是:

构造一个初始状态(锁持有数)不为零的AbstractQueuedSynchronizer,每一次countDown方法的执行会导致锁的持有次数减一,而await方法便是一直等待直到锁的持有数为0为止。