CountdownLatch至關於一個倒計時的計數器,當計數到達0時,等待這個計數器的線程就開始執行。java
下面經過代碼看一下CountdownLatch的執行效果。dom
- import java.util.concurrent.CountDownLatch;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- public class CountdownLatchTest {
- public static void main(String[] args) {
- ExecutorService service = Executors.newCachedThreadPool();
- final CountDownLatch cdOrder = new CountDownLatch(1);//計數器的初始值爲1
- final CountDownLatch cdAnswer = new CountDownLatch(3);//計數器的初始值爲3
- for(int i=0;i<3;i++){//啓動3個線程
- Runnable runnable = new Runnable(){
- public void run(){
- try {
- System.out.println("線程" + Thread.currentThread().getName() +
- "正準備接受命令");
- cdOrder.await();//3個線程都在等待計數器,當計數爲0時,都開始往下執行
- System.out.println("線程" + Thread.currentThread().getName() +
- "已接受命令");
- Thread.sleep((long)(Math.random()*10000));
- System.out.println("線程" + Thread.currentThread().getName() +
- "迴應命令處理結果");
- cdAnswer.countDown();//每一個線程結束的時候把計數器減1
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- };
- service.execute(runnable);
- }
- try {//主線程
- Thread.sleep((long)(Math.random()*10000));
- System.out.println("線程" + Thread.currentThread().getName() +
- "即將發佈命令");
- cdOrder.countDown();//將計數器的計數減1
- System.out.println("線程" + Thread.currentThread().getName() +
- "已發送命令,正在等待結果");
- //主線程在等待另一個計數器(cdAnswer)爲0,當爲0時,開始向下執行。它(cdAnswer)的初始值爲3,
- cdAnswer.await();
- System.out.println("線程" + Thread.currentThread().getName() +
- "已收到全部響應結果");
- } catch (Exception e) {
- e.printStackTrace();
- }
- service.shutdown();
- }
- }
上述CountdownLatch的代碼例子中,有兩個計數器ide
- final CountDownLatch cdOrder = new CountDownLatch(1);
至關於在運動會上發佈信號的指揮員,指揮員一吹哨子,3個「運動員」(線程)開始執行。spa
- final CountDownLatch cdAnswer = new CountDownLatch(3);
至關於公佈成績的裁判,每一個運動員到達終點時,給裁判一個信號,「我到了(至關於將計數器減1)」,當3個「運動員」(線程)都到達時,裁判纔會公佈成績,即線程
- cdAnswer.await();
下面的代碼纔會執行。get
總結:CountDownLatch能夠實現「一我的」通知「多我的」的效果,也能夠實現「多我的」通知「一我的」的效果。string