JavaTM Platform
Standard Ed. 6

java.util.concurrent
クラス CyclicBarrier

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

public class CyclicBarrier
extends Object

スレッドセットのそれぞれが共通のバリアーポイントに達するまで待機することを可能にする同期化支援機能です。CyclicBarrier は、相互に待機することが必要になることがある、固定サイズのスレッドパーティーが関係するプログラムで有用です。バリアーは、待機中のスレッドが解放されたあとで再利用できるため、cyclic (「循環式」) と呼ばれます。

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 は、失敗した同期化の試みに対して全か無かの切断モデルを使用します。割り込み、失敗、またはタイムアウトのために 1 つのスレッドがバリアーポイントを越えると、そのバリアーポイントで待機しているほかのすべてのスレッドも BrokenBarrierException をスローして異常にバリアーポイントを越えてしまいます。ほかのスレッドでもほぼ同時に割り込みが発生する場合は InterruptedException をスローします。

メモリー整合性効果:await() を呼び出す前のスレッド内のアクションは、バリアーアクションの一部であるアクションよりも happen-before であり、一方それは、他のスレッド内の対応する await() からの正常な復帰のあとのアクションよりも happen-before です。

導入されたバージョン:
1.5
関連項目:
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()
          バリアーを初期状態にリセットします。
 
クラス java.lang.Object から継承されたメソッド
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

コンストラクタの詳細

CyclicBarrier

public CyclicBarrier(int parties,
                     Runnable barrierAction)
指定された数のパーティー (スレッド) が待機状態にある場合にトリップする、新しい CyclicBarrier を作成します。バリアーのトリップ時に、指定されたバリアーアクションが、最後にバリアーに入ったスレッドにより実行されます。

パラメータ:
parties - バリアーがトリップする前に await() を呼び出す必要があるスレッドの数
barrierAction - バリアーのトリップ時に実行するコマンド。アクションが存在しない場合は null
例外:
IllegalArgumentException - parties が 1 未満の場合

CyclicBarrier

public CyclicBarrier(int parties)
指定された数のパーティー (スレッド) が待機状態にある場合にトリップする、新しい CyclicBarrier を作成します。バリアーのトリップ時に、定義済みのアクションは実行されません。

パラメータ:
parties - バリアーがトリップする前に await() を呼び出す必要があるスレッドの数
例外:
IllegalArgumentException - parties が 1 未満の場合
メソッドの詳細

getParties

public int getParties()
このバリアーのトリップに必要なパーティーの数を返します。

戻り値:
このバリアーのトリップに必要なパーティーの数

await

public int await()
          throws InterruptedException,
                 BrokenBarrierException
すべてのパーティーがこのバリアーで await を呼び出すまで待機します。

現在のスレッドが、到着する最後のスレッドではない場合、スレッドのスケジューリングに関して無効になり、次のいずれかが起きるまで待機します。

現在のスレッドで、

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

いずれかのスレッドが待機中にバリアーで reset() が実行されるか、await の呼び出し時、またはいずれかのスレッドが待機中にバリアーが破壊された場合、BrokenBarrierException がスローされます。

待機中のいずれかのスレッドで割り込みが発生した場合、待機中の他のスレッドがすべて BrokenBarrierException をスローし、バリアーが故障状態に置かれます。

現在のスレッドが到着する最後のスレッドであり、コンストラクタ内で null ではないバリアーアクションが指定される場合、現在のスレッドはアクションを実行してから、他のスレッドの続行を許可します。バリアーアクション中に例外が発生すると、現在のスレッド内にその例外が伝えられ、バリアーが故障状態に置かれます。

戻り値:
現在のスレッドの到着インデックス。インデックス getParties() - 1 は最初に到着するスレッドを、ゼロは最後に到着するスレッドを示す
例外:
InterruptedException - 待機中に現在のスレッドで割り込みが発生した場合
BrokenBarrierException - 現在のスレッドの待機中に別のスレッドで割り込みが発生したかタイムアウトした場合、バリアーがリセットされた場合、await の呼び出し時にバリアーが破壊された場合、または例外のためにバリアーアクション (存在する場合) が失敗した場合。

await

public int await(long timeout,
                 TimeUnit unit)
          throws InterruptedException,
                 BrokenBarrierException,
                 TimeoutException
すべてのパーティーがこのバリアーで await を呼び出すか、指定された待機時間が経過するまで待機します。

現在のスレッドが、到着する最後のスレッドではない場合、スレッドのスケジューリングに関して無効になり、次のいずれかが起きるまで待機します。

現在のスレッドで、

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

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

いずれかのスレッドが待機中にバリアーで reset() が実行されるか、await の呼び出し時、またはいずれかのスレッドが待機中にバリアーが破壊された場合、BrokenBarrierException がスローされます。

待機中のいずれかのスレッドで割り込みが発生した場合、待機中の他のスレッドがすべて BrokenBarrierException をスローし、バリアーが故障状態に置かれます。

現在のスレッドが到着する最後のスレッドであり、コンストラクタ内で null ではないバリアーアクションが指定される場合、現在のスレッドはアクションを実行してから、他のスレッドの続行を許可します。バリアーアクション中に例外が発生すると、現在のスレッド内にその例外が伝えられ、バリアーが故障状態に置かれます。

パラメータ:
timeout - バリアーを待機する時間
unit - timeout パラメータの時間単位
戻り値:
現在のスレッドの到着インデックス。インデックス getParties() - 1 は最初に到着するスレッドを、ゼロは最後に到着するスレッドを示す
例外:
InterruptedException - 待機中に現在のスレッドで割り込みが発生した場合
TimeoutException - 指定されたタイムアウト時間が経過した場合
BrokenBarrierException - 現在のスレッドの待機中に別のスレッドで割り込みが発生したかタイムアウトした場合、バリアーがリセットされた場合、await の呼び出し時にバリアーが破壊された場合、または例外のためにバリアーアクション (存在する場合) が失敗した場合。

isBroken

public boolean isBroken()
このバリアーが故障状態にあるかどうかを問い合わせます。

戻り値:
バリアーの構築または最後のリセット以降、割り込みまたはタイムアウトのために 1 つ以上のパーティーがこのバリアーを破壊したか、例外のためにバリアーアクションが失敗した場合は true、そうでない場合は false

reset

public void reset()
バリアーを初期状態にリセットします。いずれかのパーティーが現在バリアーで待機中の場合は、BrokenBarrierException で復帰します。他の理由で切断が発生したあとにリセットする場合は、実行が複雑になる場合があります。つまり、他の何らかの方法でスレッドを再同期して、リセットを実行するスレッドを選択する必要があります。こうした状況では、以降で使用するためにバリアーを新規作成するほうが望ましい場合があります。


getNumberWaiting

public int getNumberWaiting()
バリアーで現在待機しているパーティーの数を返します。このメソッドは、主にデバッグとアサーションで役立ちます。

戻り値:
await() で現在ブロックされているパーティーの数

JavaTM Platform
Standard Ed. 6

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

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