CountDownLatch是Java concurrent包下的一個同步工具。它可以讓一個(或多個)線程等待,直到其他線程中的某些操作完成。
本質上是一個信號量,我們把它比作一個有N個插銷的大門,它把等待(調用await)的線程擋住了, 直到其他線程把插銷去完了(調用countDown減到0),這批線程才能執行。
下面是根據oracle官方文檔改的一個例子:
/**
*
* Sample usage: Here is a pair of classes in which a group of worker threads use two countdown latches:
The first is a start signal that prevents any worker from proceeding until the driver is ready for them to proceed;
The second is a completion signal that allows the driver to wait until all workers have completed.
*/
public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
new Driver().run();
}
}
class Driver {
static final int N = 5;
public void run() throws InterruptedException {
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(N);
for (int i=0; i<N; i++) {
new Thread(new Worker(startSignal, doneSignal))
.start();
}
doSomething(); // don't let run yet
startSignal.countDown(); // let all threads proceed
doneSignal.await(); // wait for all to finish
doSomething();
}
private void doSomething() {
System.out.println("doSomething");
}
}
class Worker implements Runnable {
private CountDownLatch startSignal;
private CountDownLatch doneSignal;
public Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
this.startSignal = startSignal;
this.doneSignal = doneSignal;
}
public void run() {
try {
startSignal.await();
doWork();
doneSignal.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void doWork() {
System.out.println("worker work.");
}
}
把Driver看作是一個監工,Worker看作是工人,有5個。
看下執行結果,有助於理解整個工作過程和latch機制:
doSomething
worker work.
worker work.
worker work.
worker work.
worker work.
doSomething