首页 > 代码库 > Java并发之CountDownLatch

Java并发之CountDownLatch

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个。

  • 监工发号施令后,工人们才可以干活。所以工人干活前调用startSignal.await(), 直到监工调用startSignal.countDown() 后Worker后续doWork才开始执行。 
  • 工人们干完活后通知监工,监工才可以接着发号。所以监工调用doneSignal.await()在哪儿等着,直到工人们都干完活(调用5次doneSignal.countDown())后,才能接着执行。

看下执行结果,有助于理解整个工作过程和latch机制:

doSomething
worker work.
worker work.
worker work.
worker work.
worker work.
doSomething

Java并发之CountDownLatch