java.util.concurrent.CountDownLatchクラスの詳細と例


名前から分かるように、CountDownLatchは逆数カウントのロックで、逆数が0になるとイベント、つまりロックが開き、他の人が入ることができます.いくつかの応用場面では、ある条件が要求に達してから後のことをする必要があります.また、スレッドが完了するとイベントがトリガーされ、後続の操作が行われます.
CountDownLatchの最も重要な方法はcountDown()とawait()であり、前者は主に逆数であり、後者は逆数を0まで待つことであり、0に達しなければブロック待つしかない.
 
CountDownLatchクラスは同期カウンタであり、構造時にintパラメータが入力される.このパラメータはカウンタの初期値であり、countDown()メソッドを呼び出すたびにカウンタが1減少し、カウンタが0より大きい場合、await()メソッドはプログラムの実行をブロックする.CountDownLatchは、カウントが0に減少すると特定のイベントがトリガーされる逆カウントのラッチと見なすことができる.この特性により,サブスレッドの終了をプライマリスレッドが待つことができる.次に、選手の試合をシミュレートした例を説明する.
CountDownLatchの非常に典型的なアプリケーションシーンは、タスクを下に実行したいが、他のタスクが実行されるまで待たなければならないことです.次に実行したいタスクがCountDownLatchオブジェクトのawait()メソッドを呼び出すと、他のタスクが自分のタスクを実行した後、同じCountDownLatchオブジェクト上のcountDown()メソッドが呼び出され、このawait()メソッドを呼び出すタスクは、このCountDownLatchオブジェクトのカウント値が0に減少するまで待機をブロックします.
次の例では、CountDownLatchの使い方を簡単に説明し、100メートル競走をシミュレートし、10人の選手が準備が整い、審判の命令を待つだけだ.全員がゴールに着いたとき、試合は終わりました.
package com.eyesmore.concurrent;   
  
import java.util.concurrent.CountDownLatch;   
import java.util.concurrent.ExecutorService;   
import java.util.concurrent.Executors;   
  
public class CountDownLatchDemo {   
  
    private static final int PLAY_AMOUNT = 10;   
       
    public static void main(String[] args) {   
  
        /*
          *     :       ,               
          * */  
         CountDownLatch begin = new CountDownLatch(1);   
           
        /*
          *          ,       ,        ,     
          * */  
         CountDownLatch end = new CountDownLatch(PLAY_AMOUNT);   
         Player[] plays = new Player[PLAY_AMOUNT];   
        for(int i = 0;i<PLAY_AMOUNT;i++) {   
             plays[i] = new Player(i+1,begin,end);   
         }   
         ExecutorService exe = Executors.newFixedThreadPool(PLAY_AMOUNT);   
        for(Player p : plays) {//       
             exe.execute(p);   
         }   
         System.out.println("    ");   
         begin.countDown();//       
        try {   
             end.await();//       
         } catch (InterruptedException e) {   
             e.printStackTrace();   
         } finally {   
             System.out.println("    ");   
         }   
           
        //  :  main        ,  exe                
         exe.shutdown();   
     }   
  
}   
  
  
class Player implements Runnable {   
  
    private int id;   
       
    private CountDownLatch begin;   
       
    private CountDownLatch end;   
  
    public Player(int id, CountDownLatch begin, CountDownLatch end) {   
        super();   
        this.id = id;   
        this.begin = begin;   
        this.end = end;   
     }   
  
    public void run() {   
        try {   
             begin.await();//      countdown 0         
             Thread.sleep((long)(Math.random()*100));//            
             System.out.println("Play "+id+" has arrived. ");   
               
         } catch (InterruptedException e) {   
             e.printStackTrace();   
         } finally {   
             end.countDown();//             
         }   
     }   
}