JUC練習代碼-CountDownLatch用法

public class CountDownLatchTest01 {
    public static void main(String[] args) throws InterruptedException {
        //發令槍準備
        CountDownLatch startSignal=new CountDownLatch(1);
        //5個線程要一起到終點
        CountDownLatch endSignal=new CountDownLatch(5);
        for (int i = 0; i < 5; i++) {
            new Thread(new WorkerTest(startSignal,endSignal),"我是:"+i).start();
        }
        TimeUnit.SECONDS.sleep(3);
        startSignal.countDown();
        System.out.println("裁判:所有線程準備完畢,預備,跑!");
        endSignal.await();
        System.out.println("裁判:友誼第一,比賽第二,大家都到終點了,一起坐車回家!");
    }
}
class WorkerTest implements  Runnable{
    private CountDownLatch startSignal;
    private CountDownLatch endSignal;

    public WorkerTest(CountDownLatch startSignal, CountDownLatch endSignal) {
        this.startSignal = startSignal;
        this.endSignal = endSignal;
    }

    @Override
    public void run() {
        try {
            System.out.println(Thread.currentThread().getName()+"線程,開始等待起跑口令。。。。");
            startSignal.await();
            System.out.println(Thread.currentThread().getName()+"線程,加速gogogo");
            System.out.println(Thread.currentThread().getName()+"線程,到終點了,其他人呢");
            endSignal.countDown();

        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

CountDownLatch 被人稱作減法計數器,但是實際應用的時候,按照JDK文檔的解釋,可以有兩種場景適用。
第一個是作爲發令槍,場景是所有的線程在啓動的時候,調用CountDownLatch 的await方法進行阻塞,然後通過調用countDown()方法,讓阻塞的線程繼續執行,一般這樣我們可以new CountDownLatch(1)計數爲1
第二個是作爲一個上車關門條件,好比一輛巴士,要等所有乘客上車纔可以關門開車。主要判斷所有的線程執行完畢後,進行一些業務操作。此種場景下,一般是N個線程,則new CountDownLatch(N),然後在循環創建線程結束後,在主方法中調用await方法進行阻塞,最後在線程內部方法執行完畢後,進行countDown操作。這樣當所有線程執行完畢後,主線程纔會繼續執行。

上述代碼模擬5個線程進行跑步比賽,比賽完成後要一起坐車回家。運行結果如下:

我是:1線程,開始等待起跑口令。。。。
我是:4線程,開始等待起跑口令。。。。
我是:0線程,開始等待起跑口令。。。。
我是:3線程,開始等待起跑口令。。。。
我是:2線程,開始等待起跑口令。。。。
裁判:所有線程準備完畢,預備,跑!
我是:0線程,加速gogogo
我是:0線程,到終點了,其他人呢
我是:2線程,加速gogogo
我是:2線程,到終點了,其他人呢
我是:4線程,加速gogogo
我是:4線程,到終點了,其他人呢
我是:3線程,加速gogogo
我是:3線程,到終點了,其他人呢
我是:1線程,加速gogogo
我是:1線程,到終點了,其他人呢
裁判:友誼第一,比賽第二,大家都到終點了,一起坐車回家!

這其中要注意,第一次打印裁判所有線程準備完畢,預備,跑!如果沒有TimeUnit.SECONDS.sleep(3);打印出來的結果,會和線程的開始等待等,不會按照順序執行的。

爲了演示效果才添加了延遲,實際生產過程中,不能按照此方法來進行主線程與其他線程的同步。

思考:應用場景還有哪些?現在能想到一個,是可以作爲多線程併發的測試,比如循環創建1000個線程,最開始await,調用CountDown方法,來模擬線程併發的場景。

大家留言交流下,看看還有沒有其他適用場景?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章