Java經常使用多線程輔助工具---countdownLatch

前言

        上一篇博文說到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

相關文章
相關標籤/搜索