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; barrier = new CyclicBarrier(N, new Runnable() { public void run() { mergeRows(...); } }); for (int i = 0; i < N; ++i) new Thread(new Worker(i)).start(); waitUntilDone(); } }ここで、各ワークスレッドは行列の 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)
parties
- バリアーがトリップする前に await()
を呼び出す必要があるスレッドの数barrierAction
- バリアーがトリップされたときに実行するコマンド。アクションが存在しない場合は null
IllegalArgumentException
- parties
が 1 より小さい場合public CyclicBarrier(int parties)
parties
- バリアーがトリップする前に await()
を呼び出す必要があるスレッドの数IllegalArgumentException
- parties
が 1 より小さい場合public int getParties()
public int await() throws InterruptedException, BrokenBarrierException
現在のスレッドが、到着する最後のスレッドではない場合、スレッドのスケジューリングに関して無効になり、次のいずれかが起きるまで待機します。
reset()
を呼び出す。
現在のスレッドで、
InterruptedException
がスローされ、現在のスレッドの割り込みステータスがクリアされます。
いずれかのスレッドが待機中にバリアーで reset()
が実行されるか、await の呼び出し時、またはいずれかのスレッドが待機中にバリアーが破壊された場合、BrokenBarrierException
がスローされます。
待機中のいずれかのスレッドで割り込みが発生した場合、待機中の他のスレッドがすべて BrokenBarrierException
をスローし、バリアーが故障状態に置かれます。
現在のスレッドが到着する最後のスレッドであり、コンストラクタ内で null ではないバリアーアクションが指定される場合、現在のスレッドはアクションを実行してから、ほかのスレッドの続行を許可します。バリアーアクション中に例外が発生すると、現在のスレッド内にその例外が伝えられ、バリアーが故障状態に置かれます。
getParties()
- 1 は最初に到着するスレッドを、ゼロは最後に到着するスレッドを示すInterruptedException
- 待機中に現在のスレッドで割り込みが発生した場合BrokenBarrierException
- 現在のスレッドの待機中に別のスレッドで割り込みが発生したかタイムアウトした場合、バリアーがリセットされた場合、await
が呼び出されたときにバリアーが破壊された場合、または例外のためにバリアーアクション (存在する場合) が失敗した場合。public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException
現在のスレッドが、到着する最後のスレッドではない場合、スレッドのスケジューリングに関して無効になり、次のいずれかが起きるまで待機します。
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, 2013, Oracle and/or its affiliates. All rights reserved.