同步工具类CountDownLatch

CountDownLatch是在java1.5被引入的,跟它一起被引入的并发工具类还有CyclicBarrier、Semaphore、ConcurrentHashMap和BlockingQueue,它们都存在于java.util.concurrent包下。CountDownLatch这个类能够使一个线程等待其他线程完成各自的工作后再执行。例如,应用程序的主线程希望在负责启动框架服务的线程已经启动所有的框架服务之后再执行。

CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。

官方使用示例:

@org.junit.Test
public void test001() throws Exception {
   CountDownLatch startSignal = new CountDownLatch(1);
   CountDownLatch doneSignal = new CountDownLatch(5);

   for (int i = 0; i < 5; ++i) // create and start threads
   {
       System.out.println("start " + i);
       new Thread(new Worker(startSignal, doneSignal)).start();
       System.out.println("end   " + i);
   }

   System.out.println("hello");  // don't let run yet

   System.out.println("=========== start begin ======== " + startSignal.getCount());
   startSignal.countDown();      // let all threads proceed
   // 每调用一次这个方法,在构造函数中初始化的count值就减1。
   // 所以当N个线程都调 用了这个方法,count的值等于0,
   // 然后主线程就能通过await()方法,恢复执行自己的任务。
   System.out.println("============ start end   ======= " + startSignal.getCount());

   System.out.println("=========== done begin ======== " + doneSignal.getCount());
   doneSignal.await();           // wait for all to finish
   // 调用此方法会一直阻塞当前线程,直到计时器的值为0,除非线程被中断。
   System.out.println("=========== done end   ======= " + doneSignal.getCount());

}

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 (Exception ex) {
       } // return;
   }

   void doWork() {
       System.out.println(Thread.currentThread().getName() + " worker ");
   }
}


发表评论