モジュール java.base
パッケージ 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;
     Runnable barrierAction = () -> mergeRows(...);
     barrier = new CyclicBarrier(N, barrierAction);

     List<Thread> threads = new ArrayList<>(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)
       try {
         thread.join();
       } catch (InterruptedException ex) { }
   }
 }
ここで、各ワーカー・スレッドはマトリックスの行を処理し、すべての行が処理されるまでリアで待機します。 すべての行が処理されると、指定されたRunnableバリアー・アクションが実行されて、行をマージします。 処理結果が成功したとマージャが判定すると、done()trueを返して、各ワーカーが終了します。

バリアー・アクションがその実行時に、パーティが中断していなくてもよい場合、パーティ内のいずれかのスレッドは解放されるときに、そのアクションを実行できます。 これを容易にするため、await()の各呼出しは、バリアーの位置でそのスレッドの到着インデックスを返します。 その後、バリアー・アクションを実行するスレッドを選択できます。たとえば:

 
 if (barrier.await() == 0) {
   // log the completion of this iteration
 }

CyclicBarrierは、失敗した同期化の試みに対して全か無かの切断モデルを使用します。割り込み、失敗、またはタイム・アウトのためにスレッドが早くバリアー・ポイントを超えた場合は、そのバリアー・ポイントで待機しているその他のすべてのスレッドもBrokenBarrierExceptionをスローして異常にバリアー・ポイントを越えてしまいます。それらのスレッドもほぼ同時に割り込まれた場合はInterruptedExceptionをスローします。

メモリー整合性効果: await()を呼び出す前のスレッド内のアクションは、バリアー・アクションの一部であるアクションよりも前に発生し、一方それは、ほかのスレッド内の対応するawait()からの正常な復帰に続くアクションよりも前に発生します。

導入されたバージョン:
1.5
関連項目: