CountDownLatch的作用是,線程進入等待後,需要計數器達到0才能通行。
例子1:主線程創建了若干子線程,主線程需要等待這若干子線程結束後才結束。
例子2:線程有若干任務,分多個線程來完成,需要等待這若干任務被完成後,才繼續運行處理。
源碼:
/** * @since 1.5 * @author Doug Lea */ public class CountDownLatch { private final Sync sync; public CountDownLatch(int count) { if (count < 0) throw new IllegalArgumentException("count < 0"); this.sync = new Sync(count); } private static final class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = 4982264981922014374L; Sync(int count) { setState(count); } int getCount() { return getState(); } protected int tryAcquireShared(int acquires) { // 當數量達到0時,才能通行,否則阻塞 return (getState() == 0) ? 1 : -1; } protected boolean tryReleaseShared(int releases) { for (;;) { int c = getState(); // 如果數量達到0,則釋放失敗 if (c == 0) return false; int nextc = c-1; // 嘗試把數量遞減 if (compareAndSetState(c, nextc)) return nextc == 0; } } } public void await() throws InterruptedException { // 獲取共享鎖 sync.acquireSharedInterruptibly(1); } public boolean await(long timeout, TimeUnit unit) throws InterruptedException { // 嘗試獲取共享鎖 return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); } public void countDown() { // 釋放共享鎖 sync.releaseShared(1); } public long getCount() { return sync.getCount(); } public String toString() { return super.toString() + "[Count = " + sync.getCount() + "]"; } }