本文首發於一世流雲的專欄: https://segmentfault.com/blog...
CountDownLatch
是一個輔助同步器類,用來做計數使用,它的做用有點相似於生活中的倒數計數器,先設定一個計數初始值,當計數降到0時,將會觸發一些事件,如火箭的倒數計時。segmentfault
初始計數值在構造CountDownLatch對象時傳入,每調用一次 countDown() 方法,計數值就會減1。多線程
線程能夠調用CountDownLatch的await方法進入阻塞,當計數值降到0時,全部以前調用await阻塞的線程都會釋放。框架
注意:CountDownLatch的初始計數值一旦降到0,沒法重置。若是須要重置,能夠考慮使用CyclicBarrier。
ContDownLatch通常有如下幾種用法:this
將初始計數值爲1的 CountDownLatch 做爲一個的開關或入口:
在調用 countDown() 的線程打開入口前,全部調用 await 的線程都一直在入口處等待。spa
public class Driver { private static final int N = 10; public static void main() throws InterruptedException { CountDownLatch switcher = new CountDownLatch(1); for (int i = 0; i < N; ++i) { new Thread(new Worker(switcher)).start(); } doSomething(); switcher.countDown(); // 主線程開啓開關 } public static void doSomething() { } } class Worker implements Runnable { private final CountDownLatch startSignal; Worker(CountDownLatch startSignal) { this.startSignal = startSignal; } public void run() { try { startSignal.await(); //全部執行線程在此處等待開關開啓 doWork(); } catch (InterruptedException ex) { } } void doWork() { ...} }
將初始計數值爲N的 CountDownLatch做爲一個完成信號點:使某個線程在其它N個線程完成某項操做以前一直等待。線程
public class Driver { private static final int N = 10; public static void main() throws InterruptedException { CountDownLatch compsignal = new CountDownLatch(N); for (int i = 0; i < N; ++i) { new Thread(new Worker(compsignal)).start(); } compsignal.await(); // 主線程等待其它N個線程完成 doSomething(); } public static void doSomething() { } } class Worker implements Runnable { private final CountDownLatch compSignal; Worker(CountDownLatch compSignal) { this.compSignal = compSignal; } public void run() { try { doWork(); compSignal.countDown(); //每一個線程作完本身的事情後,就將計數器減去1 } catch (InterruptedException ex) { } } void doWork() { ...} }
類聲明:code
構造器:對象
接口:blog
關於CountDownLatch的內部實現原理,讀者能夠參考:
Java多線程進階(九)—— J.U.C之locks框架:AQS共享功能剖析(4)接口