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源码分析的主要内容,如果未能解决你的问题,请参考以下文章