CountDownLatch
CountDownLatch
类图
CountDownLatch本身没有任何父类或是实现任何接口,只含有一个内部类Sync.
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为止。