CountDownLatch理解

5483 ワード

CountDownLatch
CountDownLatchはjava 1である.5導入され、それとともに導入されたコンカレントツールクラスは、javaに存在するCyclicBarrier、Semaphore、ConcurrentHashMap、BlockingQueueである.util.concurrentパッケージの下.CountDownLatchというクラスでは、1つのスレッドが他のスレッドがそれぞれの作業を完了してから実行するのを待つことができます.たとえば、アプリケーションのプライマリ・スレッドは、フレームワーク・サービスの開始を担当するスレッドがすべてのフレームワーク・サービスを開始した後に実行することを望んでいます.
 
メソッドの説明:
 
public void countDown()
ラッチのカウントを減算し、カウントがゼロに達した場合、待機しているすべてのスレッドを解放します.現在のカウントがゼロより大きい場合は、カウントが減少します.新しいカウントがゼロの場合、スレッドスケジューリングの目的ですべての待機スレッドが再有効になります.
現在のカウントがゼロに等しい場合、アクションは発生しません.public boolean await(long timeout,TimeUnit unit)throws InterruptedExceptionは、スレッドが中断されたり、指定された待機時間を超えたりしない限り、現在のスレッドをラッチカウントがゼロになるまで待機させます.現在のカウントがゼロの場合、このメソッドはすぐにtrue値を返します.
現在のカウントがゼロより大きい場合、スレッドスケジューリングの目的で現在のスレッドは無効になり、次の3つのいずれかが発生するまでスレッドはスリープ状態になります.
countDown()メソッドを呼び出すため、カウントはゼロに達します.または他のスレッドが現在のスレッドを中断します.または指定した待機時間を超えています.
*カウントがゼロに達した場合、メソッドはtrue値を返します.
*現在のスレッドの場合、このメソッドに入るとスレッドの割り込み状態が設定されています.または、待機中に中断されるとInterruptedExceptionが放出され、現在のスレッドの中断された状態がクリアされます.
*指定した待ち時間を超えた場合はfalseを返します.時間がゼロ以下の場合、このメソッドは待機しません.
パラメータ:
timeout-待機する最長時間
unit-timeoutパラメータの時間単位.
戻り値:
カウントがゼロに達するとtrueを返します.カウントがゼロに達する前に待機時間を超えた場合はfalseを返します
放出:
InterruptedException-現在のスレッドが待機中に中断された場合
 
例1:
メインスレッドは、サブスレッドの実行が完了するのを待っています.
     
import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class CountdownLatchTest1 {     public static void main(String[] args) {         ExecutorService service = Executors. newFixedThreadPool(3);         final CountDownLatch latch = new CountDownLatch(3);         for (int i = 0; i < 3; i++) {             Runnable runnable = new Runnable() {@Override public void run(){try{System.out.println("サブスレッド"+Thread.currentThread().getName()+"実行開始");Thread.sleep((long)(Math.random() * 10000));                         System. out.println("サブスレッド"+Thread.currentThread().getName()+「実行完了」);                        latch.countDown();//現在のスレッドがこのメソッドを呼び出すと、カウントは1}catch(InterruptedException){e.printStackTrace()減少します.                    }                 }             };             service.execute(runnable); }try{System.out.println("メインスレッド"+Thread.currentThread().getName()+"サブスレッド実行完了待ち...");            latch.await();//タイマの値が0 Systemになるまで現在のスレッドをブロックする.out.println("メインスレッド"+Thread.currentThread().getName()+「実行開始...」);        } catch (InterruptedException e) {             e.printStackTrace();         }     } }
出力結果:
サブスレッドpool-1-thread-1実行開始
メインスレッドmainはサブスレッドの実行が完了するのを待っています...
サブスレッドpool-1-thread-2実行開始
サブスレッドpool-1-thread-3実行開始
サブスレッドpool-1-thread-3実行完了
サブスレッドpool-1-thread-2実行完了
サブスレッドpool-1-thread-1実行完了
メインスレッドmainが実行を開始...
例2:
100メートル競走では、4人の選手がコートに着いて審判のパスワードを待っていたが、審判がパスワードを言った.選手はそれを聞いて同時にスタートし、すべての選手がゴールに着いたとき、審判はランキングをまとめた.
 
package countdownlauch;

import java.util.concurrent.CountDownLatch;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class CountdownLatchTest2 {

    public static void main(String[] args) {

        ExecutorService service = Executors. newCachedThreadPool();

        final CountDownLatch cdOrder = new CountDownLatch(1);

        final CountDownLatch cdAnswer = new CountDownLatch(4);

        for (int i = 0; i < 4; i++) {

            Runnable runnable = new Runnable() {

                public void run() {

                    try {

                        System. out.println(" " + Thread.currentThread().getName() + " ");

                        cdOrder.await();

                        System. out.println(" " + Thread.currentThread().getName() + " ");

                        Thread. sleep((long) (Math. random() * 10000));

                        System. out.println(" " + Thread.currentThread().getName() + " ");

                        cdAnswer.countDown();

                    } catch (Exception e) {

                        e.printStackTrace();

                    }

                }

            };

            service.execute(runnable);

        }

        try {

            Thread. sleep((long) (Math. random() * 10000));

            System. out.println(" " + Thread.currentThread ().getName() + " " );

            cdOrder.countDown();

            System. out.println(" " + Thread.currentThread ().getName() + " , " );

            cdAnswer.await();

            System. out.println(" " );

            System. out.println(" " + Thread.currentThread ().getName() + " " );

        } catch (Exception e) {

            e.printStackTrace();

        }

        service.shutdown();

    }

}

出力結果:
選手pool-1-thread-1は審判がパスワードを発表するのを待っています
選手pool-1-thread-2は審判がパスワードを発表するのを待っています
選手pool-1-thread-4は審判がパスワードを発表するのを待っています
選手pool-1-thread-3は審判がパスワードを発表するのを待っています
審判mainがパスワードを発行します
選手pool-1-thread-1審判パスワードを受け付けました
審判mainはパスワードを送信し、すべての選手がゴールするのを待っています.
選手pool-1-thread-4は審判のパスワードを受け取りました
選手pool-1-thread-2は審判のパスワードを受け取った
選手pool-1-thread-3は審判のパスワードを受け取りました
選手pool-1-thread-1ゴール
選手pool-1-thread-3ゴール
選手pool-1-thread-4ゴール
選手pool-1-thread-2ゴール
すべての選手がゴールに着いた.
審判main成績ランキングまとめ