Java併發編程之JUC輔助類CountDownLatch------減小計數

一.場景引入


教師裏有很多學生,比如說有7個,其中一個是班長,他負責在全員離開後關閉大門,現在要實現一個程序,其中包括main線程在內有七個線程,main是班長。

需求是:班長要在所有人都離開教室之後才關閉大門,也就是說main線程需要在所有線程運行完之後纔打印這條語句

public static void main(String[] args) {

        for (int i = 1; i <=6 ; i++) {

            new Thread(()->{

                System.out.println(Thread.currentThread().getName()+"\t離開教室。");

            },String.valueOf(i)).start();
        }

        System.out.println("班長離開,關門。。。");

    }

這樣能實現我們的要求嗎?:

"C:\Program Files\Java\jdk1.8.0_181\bin\java.exe" "-javaagent:D:\idea\IntelliJ IDEA 2019.2.3\lib\idea_rt.jar=52240:D:\idea\IntelliJ IDEA 2019.2.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_181\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar;C:\Users\李肇京\IdeaProjects\JUC\out\production\JUC" JUC_01_SellTicket.HelperClasses.CountDownLatchDemo
班長離開,關門。。。
1	離開教室。
4	離開教室。
3	離開教室。
2	離開教室。
5	離開教室。
6	離開教室。

Process finished with exit code 0

你可以多試幾次,可能會出現符合條件的情況,但是這並不是穩定情況,不能滿足我們的需求。


二.CountDownLatch介紹

  • countDownLatch存在於java.util.cucurrent包下,是JUC輔助類的一種
  • countDownLatch這個類實現的功能是:使一個線程等待其他線程各自執行完畢後再執行
  • 是通過一個計數器來實現的,計數器的初始值是線程的數量。每當一個線程執行完畢後,計數器的值就-1,當計數器的值爲0時,表示所有線程都執行完畢,然後在閉鎖上等待的線程就可以恢復工作了

怎麼加在我們的代碼中?:

public static void main(String[] args) throws InterruptedException {

        //1.創建對象
        CountDownLatch countDownLatch = new CountDownLatch(6);
        
        for (int i = 1; i <=6 ; i++) {

            new Thread(()->{

                System.out.println(Thread.currentThread().getName()+"\t離開教室。");
                countDownLatch.countDown();//2.計數

            },String.valueOf(i)).start();
        }

        countDownLatch.await();//main線程等待
        System.out.println("班長離開,關門。。。");

    }

三.原理

CountDownLatch中有三個關鍵的方法

//調用await()方法的線程會被掛起,它會等待直到count值爲0才繼續執行
public void await() throws InterruptedException { };   
//和await()類似,只不過等待一定的時間後count值還沒變爲0的話就會繼續執行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };  
//將count值減1
public void countDown() { };  

CountDownLatch只有一個構造器:

//參數count爲計數值
public CountDownLatch(int count) {  };  

它要求我們提供一個count用來計數,也就是用來規定有幾個線程是要先執行的,這裏我們有6個學生要離開教室,所以傳入6.

由於主線程打印之前有一條語句countDownLatch.await(),所以main線程不會直接打印,而是等待循環內部將計數器逐漸減少,知道其值爲0,此時main繼續執行。這樣就完成了我們的需求。

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