CountDownLatch源码
CountDownLatch底层使用AbstractQueuedSynchronizer框架实现。
核心方法
1、CountDownLatch(int count)
使用AQS框架中state=count作为计数器,后续执行countDown()时,实际上时对state(int类型)的扣减操作。
2、countDown()
对AQS框架中的state计数器进行扣减,当扣减到state=0时表示可以继续执行后续逻辑。
sync.releaseShared该方法已被CountDownLatch中重写,如下:
protected boolean tryReleaseShared(int releases) { // Decrement count; signal when transition to zero for (;;) { int c = getState(); if (c == 0) return false; int nextc = c - 1; if (compareAndSetState(c, nextc)) return nextc == 0; } }
可以看到实际代码时对state状态的原子性扣减操作。
而且countDown()方法对返回值没有要求,执行成功即可。
3、getCount()
获取state值(int类型)
4、await()
执行等待操作,具体逻辑,如果state大于0,执行等待操作,如果state=0,执行释放等待操作。
执行代码:sync.acquireSharedInterruptibly(1)
public final void acquireSharedInterruptibly(int arg) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); if (((getState() == 0) ? 1 : -1) < 0) doAcquireSharedInterruptibly(arg); }
如果执行等待操作,底层AQS是如何操作的?
1、增加一个addWaiter(Node.SHARED)节点,创建一个Node节点,把Node节点的前置指针设置为尾节点,再以CAS方式将尾节点的next节点设置为Node节点,这样新的Node节点就可以作为尾节点。
2、获取Node节点的前置节点,如果前置节点为Head节点,则重新获取state,如果state>=0,则将Node节点设置为Head节点
收藏文章数量从多到少与“把书读薄”是一个道理