java.util.concurrent.CountDownLatch提供了一种同步辅助,可用于控制N个线程一起出发,或者阻塞到N个线程到达。关键方法是await()和countDown(),内部有一个计数器,countDown()将计数器减1,await()方法阻塞到计数器为0为止(其他线程调用countDown()可能将其唤醒),如果await()被调用时计数器已经为0,则该方法直接返回,不会阻塞。源码注释中的示例代码完美诠释了该工具类的使用场景,示例代码如下:
public class TestCountDownLatch {
public static void main(String[] args) throws InterruptedException {
final int N = 10;
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(N);
for (int i = 0; i < N; ++i) // create and start threads
new Thread(new Worker(startSignal, doneSignal)).start();
System.out.println(Thread.currentThread() + " request to start!");
// doSomethingBeforeStart(); // don't let run yet
startSignal.countDown(); // let all threads proceed
// doSomethingElse();
doneSignal.await(); // wait for all to finish
System.out.println(Thread.currentThread() + " game over!");
}
}
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 {
// wait for begin together
startSignal.await();
System.out.println(Thread.currentThread() + " do job!");
doWork();
doneSignal.countDown();
} catch (InterruptedException ex) {
}
}
void doWork() {
// ...
}
}