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。