JavaTM Platform
Standard Ed. 6

java.util.concurrent
クラス CountDownLatch

java.lang.Object
  上位を拡張 java.util.concurrent.CountDownLatch

public class CountDownLatch
extends Object

ほかのスレッドで実行中の操作セットが完了するまで、1 つ以上のスレッドを待機可能にする同期化支援機能です。  

CountDownLatch は、指定された「カウント」を使用して初期化されます。await メソッドは、countDown() メソッドの呼び出しの結果として、現在のカウントがゼロに達するまでブロックします。その後、待機中のスレッドがすべて解放され、後続の await の呼び出しがすぐに返されます。これは単発的な現象であり、カウントをリセットすることはできません。カウントをリセットするバージョンが必要な場合は、CyclicBarrier の使用を考慮してください。  

CountDownLatch は、さまざまな目的に使用できる柔軟性の高い同期ツールです。カウント 1 で初期化された CountDownLatch は、単純なオン/オフのラッチ、つまりゲートとして機能します。await を呼び出すスレッドはすべて、countDown() を呼び出すスレッドにより有効にされるまでゲートで待機します。N に初期化された CountDownLatch を使用すると、N 個のスレッドがアクションを完了するか、アクションが N 回完了するまで、あるスレッドを待機させることができます。  

CountDownLatch の特性で有用なのは、countDown を呼び出すスレッドが、カウントがゼロに達するまで処理を待機する必要がないことです。これは、単純にすべてのスレッドがパスするまで、どのスレッドも await を抜けないようにします。  

使用例は次のとおりです。 次に示すクラスのペアでは、ワーカースレッドのグループが次の 2 つのカウントダウンラッチを使用します。

 
 class Driver { // ...
   void main() throws InterruptedException {
     CountDownLatch startSignal = new CountDownLatch(1);
     CountDownLatch doneSignal = new CountDownLatch(N);

     for (int i = 0; i < N; ++i) // create and start threads
       new Thread(new Worker(startSignal, doneSignal)).start();

     doSomethingElse();            // don't let run yet
     startSignal.countDown();      // let all threads proceed
     doSomethingElse();
     doneSignal.await();           // wait for all to finish
   }
 }

 class Worker implements Runnable {
   private final CountDownLatch startSignal;
   private final CountDownLatch doneSignal;
   Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
      this.startSignal = startSignal;
      this.doneSignal = doneSignal;
   }
   public void run() {
      try {
        startSignal.await();
        doWork();
        doneSignal.countDown();
      } catch (InterruptedException ex) {} // return;
   }

   void doWork() { ... }
 }

 
 

もう 1 つの標準的な使用法は、問題を N 個の部分に分割し、各部を実行してラッチをカウントダウンする Runnable を使用して各部分を記述し、すべての Runnable を executor のキューに入れる方法です。下位部分がすべて完了すると、調整役のスレッドは await を抜けることができます。この方法でスレッドがカウントダウンを繰り返し実行する必要がある場合は、代わりに CyclicBarrier を使用してください。  

 class Driver2 { // ...
   void main() throws InterruptedException {
     CountDownLatch doneSignal = new CountDownLatch(N);
     Executor e = ...

     for (int i = 0; i < N; ++i) // create and start threads
       e.execute(new WorkerRunnable(doneSignal, i));

     doneSignal.await();           // wait for all to finish
   }
 }

 class WorkerRunnable implements Runnable {
   private final CountDownLatch doneSignal;
   private final int i;
   WorkerRunnable(CountDownLatch doneSignal, int i) {
      this.doneSignal = doneSignal;
      this.i = i;
   }
   public void run() {
      try {
        doWork(i);
        doneSignal.countDown();
      } catch (InterruptedException ex) {} // return;
   }

   void doWork() { ... }
 }

 
 

メモリー整合性効果:countDown() を呼び出す前のスレッド内のアクションは、別のスレッド内の対応する await() から正常に復帰したあとのアクションよりも happen-before です。

導入されたバージョン:
1.5

コンストラクタの概要
CountDownLatch(int count)
          指定されたカウントで初期化された CountDownLatch を構築します。
 
メソッドの概要
 void await()
          スレッドで割り込みが発生しないかぎり、ラッチのカウントダウンがゼロになるまで現在のスレッドを待機させます。
 boolean await(long timeout, TimeUnit unit)
          スレッドで割り込みが発生するか、指定された待機時間が経過しないかぎり、ラッチのカウントダウンがゼロになるまで現在のスレッドを待機させます。
 void countDown()
          ラッチのカウントを減算し、カウントがゼロに達すると待機中のスレッドをすべて解放します。
 long getCount()
          現在のカウントを返します。
 String toString()
          ラッチおよびその状態を識別する文字列を返します。
 
クラス java.lang.Object から継承されたメソッド
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

コンストラクタの詳細

CountDownLatch

public CountDownLatch(int count)
指定されたカウントで初期化された CountDownLatch を構築します。

パラメータ:
count - スレッドが await() を抜ける前に、countDown() を呼び出す回数
例外:
IllegalArgumentException - count が負の値の場合
メソッドの詳細

await

public void await()
           throws InterruptedException
スレッドで割り込みが発生しないかぎり、ラッチのカウントダウンがゼロになるまで現在のスレッドを待機させます。  

現在のカウントがゼロの場合、このメソッドはただちに復帰します。  

現在のカウントがゼロより大きい場合、現在のスレッドはスレッドのスケジューリングに関して無効になり、次の 2 つのいずれかが起きるまで待機します。

 

現在のスレッドで、

InterruptedException がスローされ、現在のスレッドの割り込みステータスがクリアされます。

例外:
InterruptedException - 待機中に現在のスレッドで割り込みが発生した場合

await

public boolean await(long timeout,
                     TimeUnit unit)
              throws InterruptedException
スレッドで割り込みが発生するか、指定された待機時間が経過しないかぎり、ラッチのカウントダウンがゼロになるまで現在のスレッドを待機させます。  

現在のカウントがゼロの場合、このメソッドはただちに値 true で復帰します。  

現在のカウントがゼロより大きい場合、現在のスレッドはスレッドのスケジューリングに関して無効になり、次の 3 つのいずれかが起きるまで待機します。

 

カウントがゼロに達すると、メソッドは値 true で復帰します。  

現在のスレッドで、

InterruptedException がスローされ、現在のスレッドの割り込みステータスがクリアされます。  

指定された待機時間が経過すると、値 false が返されます。時間がゼロまたはそれより小さい場合、メソッドは待機しません。

パラメータ:
timeout - 待機する最長時間
unit - timeout 引数の時間単位
戻り値:
カウントがゼロに達した場合は true、カウントがゼロに達する前に待機時間が経過した場合は false
例外:
InterruptedException - 待機中に現在のスレッドで割り込みが発生した場合

countDown

public void countDown()
ラッチのカウントを減算し、カウントがゼロに達すると待機中のスレッドをすべて解放します。  

現在のカウントがゼロより大きい場合、値が減らされます。新しいカウントがゼロの場合、待機中のすべてのスレッドのスケジューリングが再び可能になります。  

現在のカウントがゼロの場合、何も行われません。


getCount

public long getCount()
現在のカウントを返します。  

通常、このメソッドはデバッグとテストの場合に使用します。

戻り値:
現在のカウント

toString

public String toString()
ラッチおよびその状態を識別する文字列を返します。状態は括弧で囲まれ、文字列「Count =」 に続いて現在のカウントが含まれます。

オーバーライド:
クラス Object 内の toString
戻り値:
このラッチおよびその状態を識別する文字列

JavaTM Platform
Standard Ed. 6

バグの報告と機能のリクエスト
さらに詳しい API リファレンスおよび開発者ドキュメントについては、Java SE 開発者用ドキュメントを参照してください。開発者向けの詳細な解説、概念の概要、用語の定義、バグの回避策、およびコード実例が含まれています。

Copyright 2009 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. Documentation Redistribution Policy も参照してください。