上一篇博文說到semaphore,一個增強版的synchronized,該多線程輔助工具適用於控制對資源操做或者訪問的場景。如今有一張場景是,須要等各個線程都都執行完了再進行下一步的操做,好比須要批量對上傳的文件進行壓縮,上傳十個文件,壓縮成一個包,這時候,就須要等上傳完十個之後再進行壓縮操做,相似於阻塞,concurrent包提供了countdownLatch輔助工具。java
countdownLatch,中文翻譯是門閂的意思,相似一個計數器,控制線程執行任務的時機,以組團的方式一塊兒執行任務。該類會判斷count計數不爲0時,則呈wait狀態,也就是屏障處等待,若是爲0則繼續執行。多線程
開啓兩個線程進行計數,同時主線程在wait狀態,最後實現組團執行後續任務:工具
@Test public void testCountDownLatch() throws InterruptedException { CountDownLatch latch = new CountDownLatch(2); for (int i = 0; i < 2; i++) { new Thread(() -> { log.info("開始count,當前是線程:{},時間是:{}",Thread.currentThread().getName(),LocalDateTime.now()); try { Thread.currentThread().sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } latch.countDown(); }).start(); } log.info("等待計數器count,如今是:{}", LocalDateTime.now()); latch.await(); log.info("結束計數器count,如今是:{}", LocalDateTime.now()); }
運行結果是:spa
比較複雜的使用案例線程
模擬運動員從到場準備到開跑的過程,具體代碼以下:翻譯
@Test public void testCountDownLatch2() throws InterruptedException { CountDownLatch comingTag = new CountDownLatch(5); CountDownLatch waitTag = new CountDownLatch(1); CountDownLatch waitRunTag = new CountDownLatch(5); CountDownLatch beginTag = new CountDownLatch(1); CountDownLatch endTag = new CountDownLatch(5); for (int i = 0; i < 5; i++) { new Thread(() -> { try { Thread.sleep(5000); log.info("{}號運動員已經入場,time:{}", Thread.currentThread().getName(), LocalDateTime.now()); comingTag.countDown(); waitTag.await(); log.info("{}號運動員開始準備,time:{}", Thread.currentThread().getName(), LocalDateTime.now()); Thread.sleep(3000); waitRunTag.countDown(); log.info("{}號運動員準備結束,time:{}", Thread.currentThread().getName(), LocalDateTime.now()); beginTag.await(); log.info("{}號運動員開跑,time:{}", Thread.currentThread().getName(), LocalDateTime.now()); Thread.sleep(2000); log.info("{}號運動員跑完了,time:{}", Thread.currentThread().getName(), LocalDateTime.now()); endTag.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); } comingTag.await(); log.info("運動員所有入場,time:{}", LocalDateTime.now()); log.info("預備口令,time:{}", LocalDateTime.now()); Thread.sleep(2000); waitTag.countDown(); waitRunTag.await(); log.info("遠動員準備完畢,time:{}", LocalDateTime.now()); log.info("發令槍響,time:{}", LocalDateTime.now()); Thread.sleep(2000); beginTag.countDown(); endTag.await(); log.info("所有運動員到達終點,time:{}", LocalDateTime.now()); }
運行結果是:code