CountDownLatch的用法

本文的示例參見JavaDoc API

簡介

CountDownLatch是一個同步的輔助類,它可以允許一個或多個線程等待,直到一組在其它線程中的操作執(zhí)行完成。

一個CountDownLatch會通過一個給定的count數(shù)來被初始化。其中await()方法會一直阻塞,直到當(dāng)前的count被減到0,而這個過程是通過調(diào)用countDown()方法來實現(xiàn)的。在await()方法不再阻塞以后,所有等待的線程都會被釋放,并且任何await()的子調(diào)用都會立刻返回。這是一次性的--count不能被重置。如果你需要一種能重置count的版本,請考慮使用CyclicBarrier。

CountDownlatch是一個多功能的同步工具,可以被用于各種目的。一個CountDownLatch通過一個值為1的count被初始化,來作為一個開/關(guān)的門或門閂:所有調(diào)用了await()的線程都會在門前等待,直到門被一個線程通過調(diào)用countDown()打開。一個被初始化為N的CountDownLatch可以被用來“在N個線程都完成了某種操作(或者一些操作已經(jīng)被完成了N次)之后創(chuàng)建一個線程”。

CountDownLatch一個有用的屬性就是它不需要線程們在繼續(xù)執(zhí)行之前,調(diào)用countDown來等待count被減到0。它簡單地阻止了任何調(diào)用了await()的線程繼續(xù),直到所有的線程都能夠通過。

示例

下面請看一個應(yīng)用場景:
有1個driver和5個worker,需要滿足以下兩點要求:

  • 當(dāng)driver完成了全部的工作之后才允許worker們開始工作;
  • 當(dāng)所有的worker都完成了自己的工作之后,driver主線程才能結(jié)束。
public class Driver {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch startSignal = new CountDownLatch(1);
        CountDownLatch doneSignal = new CountDownLatch(5);

        // 依次創(chuàng)建并啟動5個worker線程
        for (int i = 0; i < 5; ++i) {
            new Thread(new Worker(startSignal, doneSignal)).start();
        }
        
        System.out.println("Driver is doing something...");
        System.out.println("Driver is Finished, start all workers ...");
        startSignal.countDown(); // Driver執(zhí)行完畢,發(fā)出開始信號,使所有的worker線程開始執(zhí)行
        doneSignal.await(); // 等待所有的worker線程執(zhí)行結(jié)束
        System.out.println("Finished.");
    }
}

class Worker implements Runnable{
    private final CountDownLatch startSignal;
    private final CountDownLatch doneSignal;
    Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
        this.startSignal = startSignal;
        this.doneSignal = doneSignal;
    }
    public void run() {
        try {
            startSignal.await(); // 等待Driver線程執(zhí)行完畢,獲得開始信號
            System.out.println("Working now ...");
            doneSignal.countDown(); // 當(dāng)前worker執(zhí)行完畢,釋放一個完成信號
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

運行結(jié)果:

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

相關(guān)閱讀更多精彩內(nèi)容

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