疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

java多线程CountDownLatch详解


 

   

  简介

  一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。用给定的计数 初始化 CountDownLatch。由于调用了 countDown() 方法,所以在当前计数到达零之前,await 方法会一直受阻塞。之后,会释放所有等待的线程,await 的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。如果需要重置计数,请考虑使用 CyclicBarrier。

  实例

  通过CountDownLatch来实现主线程和子线程通信,主线程发送命令启动子线程,子线程全部完成后通知主线程。

  代码:

  复制代码

  1 public class CountDownLatchTest {

  2 public static void main(String[] args) {

  3 final CountDownLatch cdOrder = new CountDownLatch(1);

  4 final CountDownLatch cdAnswer = new CountDownLatch(3);

  5 ExecutorService threadPool = Executors.newCachedThreadPool();

  6 for (int i = 0; i < 3; i++) {

  7 Runnable runnable = new Runnable() {

  8 @Override

  9 public void run() {

  10 try {

  11

  12 System.out.println(Thread.currentThread().getName()+"正在等待命令");

  13 cdOrder.await();//子线程等待

  14 System.out.println(Thread.currentThread().getName()+"接受命令");

  15 Thread.sleep(new Random().nextInt(10000));

  16 System.out.println(Thread.currentThread().getName()+"发出应答");

  17 cdAnswer.countDown();//当cdAnswer为0时,主线程收到回复

  18 } catch (InterruptedException e) {

  19 // TODO Auto-generated catch block

  20 e.printStackTrace();

  21 }

  22 }

  23 };

  24 threadPool.execute(runnable);

  25 }

  26

  27 /*

  28 * 主线程

  29 */

  30 try {

  31 Thread.sleep(new Random().nextInt(10000));

  32 System.out.println(Thread.currentThread().getName()+"即将发出命令");

  33 System.out.println(Thread.currentThread().getName()+"发出命令");

  34 cdOrder.countDown();//启动子线程

  35 cdAnswer.await();//等待子线程回复

  36 System.out.println(Thread.currentThread().getName()+"收到应答");

  37 } catch (InterruptedException e1) {

  38 // TODO Auto-generated catch block

  39 e1.printStackTrace();

  40 }

  41

  42

  43 threadPool.shutdown();

  44 }

  45 }

  复制代码

  注意:CountDownLatch只能启用一次,不能被重置。如果需要考虑重置,选择CyclicBarrier。