CountDownLatch

CountDownLatch

CountDownLatch是一個(gè)同步器, 允許一個(gè)或多個(gè)線程執(zhí)行完畢,再繼續(xù)執(zhí)行, 可以用來協(xié)調(diào)多個(gè)線程的同步。
CountDownLatch通過計(jì)數(shù)器實(shí)現(xiàn), 計(jì)數(shù)器的初始值是線程的數(shù)量, 每當(dāng)一個(gè)線程執(zhí)行完畢, 計(jì)數(shù)器減1, 當(dāng)計(jì)數(shù)器減為0或達(dá)到超時(shí)時(shí)間時(shí), 等待的線程開始恢復(fù)執(zhí)行。

應(yīng)用場景

  • 某一個(gè)線程等待n個(gè)線程執(zhí)行完畢, CountDownLatch初始化為CountDownLatch(n), 當(dāng)某個(gè)任務(wù)線程執(zhí)行執(zhí)行結(jié)束時(shí),調(diào)用countDown方法,計(jì)數(shù)器減1, 當(dāng)計(jì)數(shù)器減為0時(shí), 表示n個(gè)任務(wù)線程全部執(zhí)行完畢,await的線程被喚醒, 開始執(zhí)行。典型場景為,主線程等待所有子任務(wù)結(jié)束,繼續(xù)下一步。 比如服務(wù)啟動(dòng)時(shí)等待多個(gè)組件加載完畢,啟動(dòng)服務(wù)。

  • 多個(gè)線程等待某個(gè)線程執(zhí)行結(jié)束, 開始并發(fā)執(zhí)行, CountDownLatch初始化為CountDownLatch(1), 每個(gè)等待線程啟動(dòng)時(shí)調(diào)用該CountDownLatch await方法被阻塞, 當(dāng)主線程執(zhí)行完成, 計(jì)數(shù)器減1, 同時(shí)喚醒多個(gè)等待線程開始執(zhí)行。

重要方法

    // 構(gòu)造器
    public CountDownLatch(int count) {}
    //
    public void await() throws InterruptedException {}
    //
    public boolean await(long timeout, TimeUnit unit) throws InterruptedException{}
    //
    public void countDown() {}
  • 構(gòu)造器
    CountDownLatch的構(gòu)造器僅有一個(gè)int參數(shù), 代表阻塞的線程數(shù)量。
  • await
    調(diào)用此方法的線程會(huì)被掛起, 直到count值降為0才會(huì)被喚醒。
  • await(long timeout, TimeUnit unit)
    調(diào)用此方法的線程會(huì)被掛起, 直到count值降為0或超時(shí)才會(huì)被喚醒。
  • countDown
    調(diào)用此方法, count值減1

示例

  • 主線程等待n個(gè)線程執(zhí)行結(jié)束
        final CountDownLatch countDownLatch = new CountDownLatch(10);
        for(int i=0; i<10; i++){
            final int finalI = i;
            Runnable thread = new Runnable() {
                @Override
                public void run() {
                    System.out.println(finalI);
                    countDownLatch.countDown();
                }
            };
            thread.run();
        }
        countDownLatch.await();
  • 并發(fā)執(zhí)行
        ExecutorService service = Executors.newCachedThreadPool();
        final CountDownLatch countDownLatch = new CountDownLatch(1);
        final CountDownLatch countDownLatch1 = new CountDownLatch(10);
        final int[] a = {0};
        for(int i=0; i<10; i++){
            Runnable thread = new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println(a[0]);
                        countDownLatch.await();
                        a[0] += 1;
                        countDownLatch1.countDown();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
            service.execute(thread);
        }
        countDownLatch.countDown();
        countDownLatch1.await();
        System.out.println(a[0]);

原理解析

TODO AQS

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容