public class CyclicBarrier extends Object
CyclicBarrier
は、オプションのRunnable
コマンドをサポートします。これは、パーティ内の最後のスレッドが到着した後で、スレッドが解放される前にバリアー・ポイントごとに1回実行されます。このバリアー・アクションは、いずれかのパーティが処理を続行する前に共有状態を更新するために役立ちます。
使用例: 次に、並列分解設計でのバリアーの使用例を示します。
class Solver {
final int N;
final float[][] data;
final CyclicBarrier barrier;
class Worker implements Runnable {
int myRow;
Worker(int row) { myRow = row; }
public void run() {
while (!done()) {
processRow(myRow);
try {
barrier.await();
} catch (InterruptedException ex) {
return;
} catch (BrokenBarrierException ex) {
return;
}
}
}
}
public Solver(float[][] matrix) {
data = matrix;
N = matrix.length;
Runnable barrierAction =
new Runnable() { public void run() { mergeRows(...); }};
barrier = new CyclicBarrier(N, barrierAction);
List<Thread> threads = new ArrayList<Thread>(N);
for (int i = 0; i < N; i++) {
Thread thread = new Thread(new Worker(i));
threads.add(thread);
thread.start();
}
// wait until done
for (Thread thread : threads)
thread.join();
}
}
ここで、各ワーカー・スレッドは行列の1行を処理して、すべての行が処理されるまでバリアーで待機します。すべての行が処理されると、指定されたRunnable
バリアー・アクションが実行されて、行をマージします。処理結果が成功したとマージャが判定すると、done()
がtrue
を返して、各ワーカーが終了します。
バリアー・アクションがその実行時に、パーティが中断していなくてもよい場合、パーティ内のいずれかのスレッドは解放されるときに、そのアクションを実行できます。これを容易にするため、await()
の各呼出しは、バリアーの位置でそのスレッドの到着インデックスを返します。その後、バリアー・アクションを実行するスレッドを選択できます。次に例を示します。
if (barrier.await() == 0) {
// log the completion of this iteration
}
CyclicBarrier
は、失敗した同期化の試みに対して全か無かの切断モデルを使用します。割り込み、失敗、またはタイム・アウトのためにスレッドが早くバリアー・ポイントを超えた場合は、そのバリアー・ポイントで待機しているその他のすべてのスレッドもBrokenBarrierException
をスローして異常にバリアー・ポイントを越えてしまいます。それらのスレッドもほぼ同時に割り込まれた場合はInterruptedException
をスローします。
メモリー整合性効果: await()
を呼び出す前のスレッド内のアクションは、バリアー・アクションの一部であるアクションよりも前に発生し、一方それは、ほかのスレッド内の対応するawait()
からの正常な復帰に続くアクションよりも前に発生します。
CountDownLatch
コンストラクタと説明 |
---|
CyclicBarrier(int parties)
指定された数のパーティ(スレッド)が待機状態にある場合にトリップする、新しい
CyclicBarrier を作成します。バリアーのトリップ時に、定義済みのアクションは実行されません。 |
CyclicBarrier(int parties, Runnable barrierAction)
指定された数のパーティ(スレッド)が待機状態にある場合にトリップする、新しい
CyclicBarrier を作成します。バリアーのトリップ時に、指定されたバリアー・アクションが、最後にバリアーに入ったスレッドにより実行されます。 |
修飾子と型 | メソッドと説明 |
---|---|
int |
await()
すべてのパーティがこのバリアーで
await を呼び出すまで待機します。 |
int |
await(long timeout, TimeUnit unit)
すべてのパーティがこのバリアーで
await を呼び出すか、指定された待機時間が経過するまで待機します。 |
int |
getNumberWaiting()
バリアーで現在待機しているパーティの数を返します。
|
int |
getParties()
このバリアーのトリップに必要なパーティの数を返します。
|
boolean |
isBroken()
このバリアーが故障状態にあるかどうかを問い合わせます。
|
void |
reset()
バリアーを初期状態にリセットします。
|
public CyclicBarrier(int parties, Runnable barrierAction)
CyclicBarrier
を作成します。バリアーのトリップ時に、指定されたバリアー・アクションが、最後にバリアーに入ったスレッドにより実行されます。parties
- バリアーがトリップする前にawait()
を呼び出す必要があるスレッドの数barrierAction
- バリアーがトリップされたときに実行するコマンド。アクションが存在しない場合はnull
IllegalArgumentException
- parties
が1より小さい場合public CyclicBarrier(int parties)
CyclicBarrier
を作成します。バリアーのトリップ時に、定義済みのアクションは実行されません。parties
- バリアーがトリップする前にawait()
を呼び出す必要があるスレッドの数IllegalArgumentException
- parties
が1より小さい場合public int getParties()
public int await() throws InterruptedException, BrokenBarrierException
await
を呼び出すまで待機します。
現在のスレッドが、到着する最後のスレッドではない場合、スレッドのスケジューリングに関して無効になり、次のいずれかが起きるまで待機します。
reset()
を呼び出す。
現在のスレッドで、
InterruptedException
がスローされ、現在のスレッドの割込みステータスがクリアされます。
いずれかのスレッドが待機中にバリアーでreset()
が実行されるか、awaitの呼出し時、またはいずれかのスレッドが待機中にバリアーが破壊された
場合、BrokenBarrierException
がスローされます。
待機中のいずれかのスレッドで割り込みが発生した場合、待機中の他のスレッドがすべてBrokenBarrierException
をスローし、バリアーが故障状態に置かれます。
現在のスレッドが到着する最後のスレッドであり、コンストラクタ内でnullではないバリアー・アクションが指定される場合、現在のスレッドはアクションを実行してから、ほかのスレッドの続行を許可します。バリアー・アクション中に例外が発生すると、現在のスレッド内にその例外が伝えられ、バリアーが故障状態に置かれます。
getParties() - 1
は最初に到着するスレッドを、ゼロは最後に到着するスレッドを示すInterruptedException
- 待機中に現在のスレッドで割込みが発生した場合BrokenBarrierException
- 現在のスレッドの待機中に別のスレッドで割込みが発生したかタイム・アウトした場合、バリアーがリセットされた場合、await
が呼び出されたときにバリアーが破壊された場合、または例外のためにバリアー・アクション(存在する場合)が失敗した場合public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException
await
を呼び出すか、指定された待機時間が経過するまで待機します。
現在のスレッドが、到着する最後のスレッドではない場合、スレッドのスケジューリングに関して無効になり、次のいずれかが起きるまで待機します。
reset()
を呼び出す。
現在のスレッドで、
InterruptedException
がスローされ、現在のスレッドの割込みステータスがクリアされます。
指定された待機時間が経過すると、TimeoutException
がスローされます。時間がゼロまたはそれより小さい場合、メソッドは待機しません。
いずれかのスレッドが待機中にバリアーでreset()
が実行されるか、awaitの呼出し時、またはいずれかのスレッドが待機中にバリアーが破壊された
場合、BrokenBarrierException
がスローされます。
待機中のいずれかのスレッドで割り込みが発生した場合、待機中の他のスレッドがすべてBrokenBarrierException
をスローし、バリアーが故障状態に置かれます。
現在のスレッドが到着する最後のスレッドであり、コンストラクタ内でnullではないバリアー・アクションが指定される場合、現在のスレッドはアクションを実行してから、ほかのスレッドの続行を許可します。バリアー・アクション中に例外が発生すると、現在のスレッド内にその例外が伝えられ、バリアーが故障状態に置かれます。
timeout
- バリアーを待機する時間unit
- タイムアウト・パラメータの時間単位getParties() - 1
は最初に到着するスレッドを、ゼロは最後に到着するスレッドを示すInterruptedException
- 待機中に現在のスレッドで割込みが発生した場合TimeoutException
- 指定されたタイム・アウトが経過した場合。この場合はバリアーが破壊されます。BrokenBarrierException
- 現在のスレッドの待機中に別のスレッドで割込みが発生したかタイム・アウトした場合、バリアーがリセットされた場合、await
が呼び出されたときにバリアーが破壊された場合、または例外のためにバリアー・アクション(存在する場合)が失敗した場合public boolean isBroken()
true
。それ以外の場合はfalse
。public void reset()
BrokenBarrierException
で復帰します。ほかの理由で切断が発生したあとにリセットする場合は、実行が複雑になる場合があることに注意してください。つまり、ほかの何らかの方法でスレッドを再同期し、リセットを実行するスレッドを選択する必要があります。こうした状況では、以降で使用するためにバリアーを新規作成するほうが望ましい場合があります。public int getNumberWaiting()
await()
で現在ブロックされているパーティの数 バグまたは機能を送信
詳細なAPIリファレンスおよび開発者ドキュメントについては、Java SEのドキュメントを参照してください。そのドキュメントには、概念的な概要、用語の定義、回避方法、有効なコード例などの、開発者を対象にしたより詳細な説明が含まれています。
Copyright© 1993, 2014, Oracle and/or its affiliates. All rights reserved.