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 つのカウントダウンラッチを使用します。
- 最初のクラスは、ドライバの進行準備ができるまで、ワーカが先に進むのを防ぐ開始信号である
- 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() { ... }
}
- 導入されたバージョン:
- 1.5
コンストラクタの概要 |
CountDownLatch(int count)
指定されたカウントで初期化された CountDownLatch を構築します。 |
メソッドの概要 |
void |
await()
スレッドで割り込み が発生しないかぎり、ラッチのカウントダウンがゼロになるまで現在のスレッドを待機させます。 |
boolean |
await(long timeout,
TimeUnit unit)
スレッドで割り込み が発生するか、指定された待機時間が経過しないかぎり、ラッチのカウントダウンがゼロになるまで現在のスレッドを待機させます。 |
void |
countDown()
ラッチのカウントを減算し、カウントがゼロに達すると待機中のスレッドをすべて解放します。 |
long |
getCount()
現在のカウントを返します。 |
String |
toString()
このラッチおよびその状態を識別する文字列を返します。 |
CountDownLatch
public CountDownLatch(int count)
- 指定されたカウントで初期化された CountDownLatch を構築します。
- パラメータ:
count
- スレッドが await()
を抜ける前に、countDown()
を呼び出す回数
- 例外:
IllegalArgumentException
- count が 0 より小さい場合
await
public void await()
throws InterruptedException
- スレッドで
割り込み
が発生しないかぎり、ラッチのカウントダウンがゼロになるまで現在のスレッドを待機させます。
現在のカウント
がゼロの場合、このメソッドはただちに復帰します。
現在のカウント
がゼロより大きい場合、現在のスレッドはスレッドのスケジューリングについては無効とされ、次の 2 つのどちらかが発生するまで待機します。
現在のスレッドが、
- このメソッドへのエントリ上で設定された割り込みステータスを保持するか、
- 待機中に
割り込み
が発生した場合、
InterruptedException
がスローされ、現在のスレッドの割り込みステータスがクリアされます。
- 例外:
InterruptedException
- 待機中に、現在のスレッドで割り込みが発生した場合
await
public boolean await(long timeout,
TimeUnit unit)
throws InterruptedException
- スレッドで
割り込み
が発生するか、指定された待機時間が経過しないかぎり、ラッチのカウントダウンがゼロになるまで現在のスレッドを待機させます。
現在のカウント
がゼロの場合、このメソッドはただちに値 true で復帰します。
現在のカウント
がゼロより大きい場合、現在のスレッドはスレッドのスケジューリングについては無効とされ、次の 3 つのいずれかが発生するまで待機します。
countDown()
メソッドの呼び出しにより、カウントがゼロに達するか、- 別のスレッドが現在のスレッドに
割り込み
を行うか、 - 指定された待機時間が経過する
カウントがゼロに達すると、メソッドは値 true で復帰します。
現在のスレッドが、
- このメソッドへのエントリ上で設定された割り込みステータスを保持するか、
- 待機中に
割り込み
が発生した場合、
InterruptedException
がスローされ、現在のスレッドの割り込みステータスがクリアされます。
指定された待機時間が経過すると、値 false が返されます。時間がゼロまたはそれより小さい場合、メソッドは待機しません。
- パラメータ:
timeout
- 待機する最長時間unit
- timeout 引数の時間単位
- 戻り値:
- カウントがゼロに達した場合は true、カウントがゼロに達する前に待機時間が経過した場合は false
- 例外:
InterruptedException
- 待機中に、現在のスレッドで割り込みが発生した場合
countDown
public void countDown()
- ラッチのカウントを減算し、カウントがゼロに達すると待機中のスレッドをすべて解放します。
現在のカウント
がゼロより大きい場合、値が減らされます。新しいカウントがゼロの場合、待機中のすべてのスレッドのスケジューリングが再び可能になります。
現在のカウント
がゼロの場合、何も行われません。
getCount
public long getCount()
- 現在のカウントを返します。
通常、このメソッドはデバッグおよびテスト目的で使用します。
- 戻り値:
- 現在のカウント
toString
public String toString()
- このラッチおよびその状態を識別する文字列を返します。状態は括弧で囲まれ、文字列「Count =」に続いて現在のカウントが指定されます。
- オーバーライド:
- クラス
Object
内の toString
- 戻り値:
- このラッチおよびその状態を識別する文字列
バグの報告と機能のリクエスト
さらに詳しい API リファレンスおよび開発者ドキュメントについては、Java 2 SDK SE 開発者用ドキュメントを参照してください。開発者向けの詳細な解説、概念の概要、用語の定義、バグの回避策、およびコード実例が含まれています。Copyright 2004 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. Documentation Redistribution Policy も参照してください。