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