java多線程等待協調工作:CountDownLatch類的高級應用


一:說明

 

基本上對於線程初步了解的人,都是使用synchronized來同步線程的,也確實,它也是可以滿足一些常用的問題。那么我們來說一些它不能解決的問題(其實是不怎么好解決的問題,並不是真的不能解決)

 

1.1:場景一

問題:

  在一場運動會上,有10個運動員,只有當10個運動員都准備完畢后,所有人才能一起跑,否則就算前面的運動員在幾天前都做好准備了,只要最后一個運動員沒有做好准備,那所有的人都不能跑,有失公平嘛!

常規的解決方法

  定義一個計數器,並且對它的操作進行同步,當每有一個准備完畢后,增加這個計數器的准備好的數量,當達到10個的時候,全部一起運行,那么大概的代碼是這樣子的,程序要定義一個死循環,只有當所有的條件滿足的時候,才能往下走,否則就一直循環。

 

1.2:場景二:多線程下載文件,我們使用它來作為例子

  為了提高下載效率,充分利用網絡資源,決定使用多線程來下載一個文件,那么每一個線程分別下載一小段文件,當所有的文件下載完之后,對所有的文件進行合並,那就得到完整的文件了。

 

    理論上來說代碼是這樣子的(理論上,實際上是錯誤的)

 

    public static void go(){
        System.out.println("開始下載文件,開啟10個線程下載");
        for(int i = 0 ; i < 10 ; i ++){
            new Thread(){
                public void run(){
                    System.out.println("文件下載完成");
                }
            }.start();
        }
        //開始合並文件
        System.out.println("所有文件下載完成,開始合並文件");
    }

 

上面的代碼開啟了10個線程去下載文件,下載完之后,執行合並文件的方法,但是由於多線程,合並文件的時候,線程肯定是沒有執行完成的。

要怎么辦呢?這個時候命名用synchronized肯定是沒用的,synchronized只是使得同一時間只有一個線程通過

 

 

 

二:CountDownLatch使用所有的線程等待。

 CountDownLatch這個類,可以使得所有的線程,全部停在那一個位置,達到指定的條件的時候,才可以運行。先給出代碼 

 

    public static void main(String[] args) throws Exception {
        //這里的構造方法參數是指需要達到完成的數量個數
        final CountDownLatch cd = new CountDownLatch(10);
        
        for(int i = 0 ; i < 10 ; i ++){
            new Thread(){
                public void run(){
                    System.out.println("文件下載完成");
                    //還記得之前構造方法的參數嗎,10,每調用一個countDown()方法,都會使得這個數值減1
                    cd.countDown();
                }
            }.start();
        }
        
        //這個方法,會使得所有的線程暫停,只有當cd構造方法里面的值為0的時候,才能走通,調用一個countDown()方法,都會使得這個數值減1
        cd.await();
        //或者使用這個方法,這個方法也會等待數值到0才會往下面走,但是如果達到指定的時間,還沒有達到0,它也會走過
//        cd.await(1000, TimeUnit.MINUTES);
        //開始合並文件
        System.out.println("所有文件下載完成,開始合並文件");
        
    }

 

執行結果是這樣的

 

文件下載完成
文件下載完成
文件下載完成
文件下載完成
文件下載完成
文件下載完成
文件下載完成
文件下載完成
文件下載完成
文件下載完成
所有文件下載完成,開始合並文件

 

 

這樣就滿足條件啦


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM