CountDownLatch 原始碼分析
阿新 • • 發佈:2018-12-15
CountDownLatch
(鎖存器/閉鎖)是基於同步器實現的同步輔助類,在完成一組正在其他執行緒中執行的操作之前,它允許一個或多個執行緒一直等待。
用計數值 N 初始化的 CountDownLatch 可以使一個或多個執行緒在其他 N 個執行緒完成某項操作之前一直等待,或者使其在某項操作完成 N 次之前一直等待。
建立例項
private static final class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = 4982264981922014374L; Sync(int count) { // 寫入狀態值 setState(count); } int getCount() { return getState(); } /** * 只有當同步狀態為 0 時才能獲取成功,否則進入阻塞 * created by ZXD at 15 Dec 2018 T 12:05:56 * @param acquires * @return */ @Override protected int tryAcquireShared(int acquires) { return getState() == 0 ? 1 : -1; } /** * 嘗試將狀態值遞減 1,如果遞減到 0,則釋放在閉鎖上阻塞等待的所有執行緒 */ @Override protected boolean tryReleaseShared(int releases) { // Decrement count; signal when transition to zero for (;;) { final int c = getState(); if (c == 0) { return false; } // 狀態值遞減 1 final int nextc = c - 1; if (compareAndSetState(c, nextc)) { // 已經遞減到 0,則返回 true return nextc == 0; } } } } private final Sync sync; /** * 建立計數值為 count 的閉鎖 */ public CountDownLatch(int count) { if (count < 0) { throw new IllegalArgumentException("count < 0"); } sync = new Sync(count); }
同步阻塞
/** * 阻塞等待閉鎖的狀態值遞減到 0、或執行緒被中斷為止 */ public void await() throws InterruptedException { sync.acquireSharedInterruptibly(1); } /** * 在指定的超時時間內阻塞等待閉鎖的狀態值遞減到 0、或執行緒被中斷為止 */ public boolean await(long timeout, TimeUnit unit) throws InterruptedException { return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); }
遞減閉鎖狀態值,如果遞減到 0,則釋放所有在閉鎖上阻塞等待的執行緒
/**
* 遞減閉鎖狀態值,如果遞減到 0,則釋放所有在閉鎖上阻塞等待的執行緒
*/
public void countDown() {
sync.releaseShared(1);
}