CountDownLatch

CountDownLatch

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

應用場景

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

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

重要方法

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

示例

  • 主線程等待n個線程執(zhí)行結束
        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

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

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