JUC學習之CountDownLatch入門

一、簡介

官網的介紹如下:

CountDownLatch:允許一個或多個線程等待直到在其他線程中執行的一組操作完成的同步輔助。

CountDownLatch用給定的計數初始化。 await方法阻塞,直到由於countDown()方法的調用而導致當前計數達到零,之後所有等待線程被釋放,並且任何後續的await 調用立即返回。

CountDownLatch使一個線程等待其他線程各自執行完畢後再執行,是通過一個計數器來實現的,計數器的初始值是線程的數量。每當一個線程執行完畢後,計數器的值就-1,當計數器的值爲0時,表示所有線程都執行完畢,然後在閉鎖上等待的線程就可以恢復工作了。

二、主要API

  • 構造方法
//參數count爲計數值,一般爲線程
public CountDownLatch(int count) {
    if (count < 0) throw new IllegalArgumentException("count < 0");
    this.sync = new Sync(count);
}
  • 常用方法

void

await()

調用await()方法的線程會被掛起,它會等待直到count值爲0才繼續執行

boolean

await(long timeout, TimeUnit unit)

和await()類似,只不過等待一定的時間後count值還沒變爲0的話就會繼續執行

void

countDown()

將count值減1

long

getCount()

返回當前count值

三、示例

CountDownLatch的一個非常典型的應用場景是:有一個任務想要往下執行,但必須要等到其他的任務執行完畢後纔可以繼續往下執行。假如我們這個想要繼續往下執行的任務調用一個CountDownLatch對象的await()方法,其他的任務執行完自己的任務後調用同一個CountDownLatch對象上的countDown()方法,這個調用await()方法的任務將一直阻塞等待,直到這個CountDownLatch對象的計數值減到0爲止。

舉個例子:

五個學生,一個老師,學生們都在自習,只有老師纔有教室的一把鑰匙,老師必須等到5個學生都離開教室之後才能鎖門,不可能學生還沒走老師就把教室給鎖了,顯然存在一個線程阻塞等待另外的線程必須完成之後纔可以執行的場景。

代碼實現:

public class T01_CountDownLatch {
    public static void main(String[] args) {
        //模擬五個學生
        CountDownLatch countDownLatch = new CountDownLatch(5);
        for (int i = 1; i <= 5; i++) {
            final int num = i;
            new Thread(() -> {
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("學生" + num + "離開教室...");
                //將計數器減一
                countDownLatch.countDown();
            }).start();
        }

        //老師一直在等待,即主線程一直阻塞
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //直到計數器變爲0時才執行
        System.out.println("所有學生都離開了,老師拿鑰匙鎖門....");
    }
}

運行結果:

學生4離開教室...
學生1離開教室...
學生2離開教室...
學生3離開教室...
學生5離開教室...
所有學生都離開了,老師拿鑰匙鎖門....

 

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