簡介 一個同步輔助類,在完成一組正在其他線程中執行的操作之前,它允許一個或多個線程一直等待。用給定的計數 初始化 CountDownLatch。由於調用了 countDown() 方法,所以在當前計數到達零之前,await 方法會一直受阻塞。之後,會釋放所有等待的線程,await 的所有後續調用都將
- 簡介
一個同步輔助類,在完成一組正在其他線程中執行的操作之前,它允許一個或多個線程一直等待。用給定的計數 初始化 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。