Java并发同步工具类之CountDownLatch

    CountDownLatch的作用是:允许一个或多个线程等待,直到一组在其他线程中执行的操作完成。

    CountDownLatch使用给定的一个数值(计数器)进行初始化,当调用await方法时,线程会被阻塞直到CountDownLatch计数器的值变成0。调用countDown方法计数器就会减一。

直接看javadoc提供的demo

demo1:使用一个开始信号来阻塞所有线程的运行,直到Dirver(主线程)准备OK。
                使用一个完成信号让Dirver(主线程)阻塞,直到所有线程运行完成。
  
class Driver { // ...
     void main() throws InterruptedException {
       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();
 
       doSomethingElse();            // don't let run yet
       startSignal.countDown();      // let all threads proceed
       doSomethingElse();
       doneSignal.await();           // wait for all to finish
     }
   }
 
   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() { ... }
   }




    有两个CountDownLatch  的实例,startSignal(开始信号) 和 doneSignal(完成信号)。

    Driver 类的main方法启动了N个Worker线程,所有Worker线程在运行到startSignal.await()时会被阻塞直到Driver的main里面startSignal.countDown()被执行。

    Driver 类的main方法执行到doneSignal.await()时,main线程就会阻塞直到N个Worker线程运行完成。doneSignal的计数器值为N,每个Worker线程运行完成后都会调用doneSignal.countDown()方法(使得doneSignal的计数器减一),当doneSignal的计数器减到0时,main线程将不再阻塞。

demo2
将一个任务分解为N个部分,当每个部分都运行完成后,主线程才继续往下运行
   
class Driver2 { // ...
     void main() throws InterruptedException {
       CountDownLatch doneSignal = new CountDownLatch(N);
       Executor e = ...
 
       for (int i = 0; i < N; ++i) // create and start threads
         e.execute(new WorkerRunnable(doneSignal, i));
 
       doneSignal.await();           // wait for all to finish
     }
   }
 
   class WorkerRunnable implements Runnable {
     private final CountDownLatch doneSignal;
     private final int i;
     WorkerRunnable(CountDownLatch doneSignal, int i) {
        this.doneSignal = doneSignal;
        this.i = i;
     }
     public void run() {
        try {
          doWork(i);
          doneSignal.countDown();
        } catch (InterruptedException ex) {} // return;
     }
 
     void doWork() { ... }
   }








你可能感兴趣的:(多线程,并发,CountDownLatch,java并发同步)