CountDownLatch实现了通过一个计数,来控制一个或多个线程是否需要一直阻塞等待。
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(Number);
初始化时指定一个数字,通过await()方法控制线程阻塞等待。
startSignal.await();
然后通过countDown()方法实现对初始化时指定的数字减1,每调用一次就减1一次,直到指定的数字变量减为0,这个时候await()实现的阻塞状态被改变,由此程序得以继续向下执行。
doneSignal.countDown();
我们可以看一个JDK中官方给的例子:
例子中,用到了两个CountDownlatch对象,一个用于控制线程开始工作,一个控制等待所有线程工作完成。
package basic.aqs;import java.util.concurrent.CountDownLatch;class Driver { // ...void main() throws InterruptedException {CountDownLatch startSignal = new CountDownLatch(1);CountDownLatch doneSignal = new CountDownLatch(15);for (int i = 0; i < 15; ++i) // create and start threadsnew Thread(new Worker(startSignal, doneSignal)).start();//doSomethingElse(); // don't let run yet开始前的准备工作startSignal.countDown(); // let all threads proceed 让线程正常工作取消阻塞//doSomethingElse();doneSignal.await(); // wait for all to finish等待所有线程执行完成}}
package basic.aqs;import java.util.concurrent.CountDownLatch;class Worker implements Runnable {private final CountDownLatch startSignal;private final CountDownLatch doneSignal;Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {this.startSignal = startSignal;this.doneSignal = doneSignal;}public void run() {try {startSignal.await();doWork();doneSignal.countDown();} catch (InterruptedException ex) {} // return;}void doWork() {}}
另外,await方法可以实现控制等待的时间,超过这个时间的就不等待阻塞了,直接执行后面的操作。
countDownLatch.await(10,TimeUnit.MILLISECONDS);
AQS(AbstractQueuedSynchronizer)同步组件之一。