jdk/src/share/classes/java/util/concurrent/CyclicBarrier.java
changeset 14325 622c473a21aa
parent 9242 ef138d47df58
child 18768 f2638f396c41
equal deleted inserted replaced
14324:3510b4bf90ee 14325:622c473a21aa
    32  * Expert Group and released to the public domain, as explained at
    32  * Expert Group and released to the public domain, as explained at
    33  * http://creativecommons.org/publicdomain/zero/1.0/
    33  * http://creativecommons.org/publicdomain/zero/1.0/
    34  */
    34  */
    35 
    35 
    36 package java.util.concurrent;
    36 package java.util.concurrent;
    37 import java.util.concurrent.locks.*;
    37 import java.util.concurrent.locks.Condition;
       
    38 import java.util.concurrent.locks.ReentrantLock;
    38 
    39 
    39 /**
    40 /**
    40  * A synchronization aid that allows a set of threads to all wait for
    41  * A synchronization aid that allows a set of threads to all wait for
    41  * each other to reach a common barrier point.  CyclicBarriers are
    42  * each other to reach a common barrier point.  CyclicBarriers are
    42  * useful in programs involving a fixed sized party of threads that
    43  * useful in programs involving a fixed sized party of threads that
    50  * This <em>barrier action</em> is useful
    51  * This <em>barrier action</em> is useful
    51  * for updating shared-state before any of the parties continue.
    52  * for updating shared-state before any of the parties continue.
    52  *
    53  *
    53  * <p><b>Sample usage:</b> Here is an example of
    54  * <p><b>Sample usage:</b> Here is an example of
    54  *  using a barrier in a parallel decomposition design:
    55  *  using a barrier in a parallel decomposition design:
    55  * <pre>
    56  *
       
    57  *  <pre> {@code
    56  * class Solver {
    58  * class Solver {
    57  *   final int N;
    59  *   final int N;
    58  *   final float[][] data;
    60  *   final float[][] data;
    59  *   final CyclicBarrier barrier;
    61  *   final CyclicBarrier barrier;
    60  *
    62  *
    88  *     for (int i = 0; i < N; ++i)
    90  *     for (int i = 0; i < N; ++i)
    89  *       new Thread(new Worker(i)).start();
    91  *       new Thread(new Worker(i)).start();
    90  *
    92  *
    91  *     waitUntilDone();
    93  *     waitUntilDone();
    92  *   }
    94  *   }
    93  * }
    95  * }}</pre>
    94  * </pre>
    96  *
    95  * Here, each worker thread processes a row of the matrix then waits at the
    97  * Here, each worker thread processes a row of the matrix then waits at the
    96  * barrier until all rows have been processed. When all rows are processed
    98  * barrier until all rows have been processed. When all rows are processed
    97  * the supplied {@link Runnable} barrier action is executed and merges the
    99  * the supplied {@link Runnable} barrier action is executed and merges the
    98  * rows. If the merger
   100  * rows. If the merger
    99  * determines that a solution has been found then <tt>done()</tt> will return
   101  * determines that a solution has been found then <tt>done()</tt> will return
   103  * it is executed, then any of the threads in the party could execute that
   105  * it is executed, then any of the threads in the party could execute that
   104  * action when it is released. To facilitate this, each invocation of
   106  * action when it is released. To facilitate this, each invocation of
   105  * {@link #await} returns the arrival index of that thread at the barrier.
   107  * {@link #await} returns the arrival index of that thread at the barrier.
   106  * You can then choose which thread should execute the barrier action, for
   108  * You can then choose which thread should execute the barrier action, for
   107  * example:
   109  * example:
   108  * <pre>  if (barrier.await() == 0) {
   110  *  <pre> {@code
   109  *     // log the completion of this iteration
   111  * if (barrier.await() == 0) {
   110  *   }</pre>
   112  *   // log the completion of this iteration
       
   113  * }}</pre>
   111  *
   114  *
   112  * <p>The <tt>CyclicBarrier</tt> uses an all-or-none breakage model
   115  * <p>The <tt>CyclicBarrier</tt> uses an all-or-none breakage model
   113  * for failed synchronization attempts: If a thread leaves a barrier
   116  * for failed synchronization attempts: If a thread leaves a barrier
   114  * point prematurely because of interruption, failure, or timeout, all
   117  * point prematurely because of interruption, failure, or timeout, all
   115  * other threads waiting at that barrier point will also leave
   118  * other threads waiting at that barrier point will also leave
   202             if (Thread.interrupted()) {
   205             if (Thread.interrupted()) {
   203                 breakBarrier();
   206                 breakBarrier();
   204                 throw new InterruptedException();
   207                 throw new InterruptedException();
   205             }
   208             }
   206 
   209 
   207            int index = --count;
   210             int index = --count;
   208            if (index == 0) {  // tripped
   211             if (index == 0) {  // tripped
   209                boolean ranAction = false;
   212                 boolean ranAction = false;
   210                try {
   213                 try {
   211                    final Runnable command = barrierCommand;
   214                     final Runnable command = barrierCommand;
   212                    if (command != null)
   215                     if (command != null)
   213                        command.run();
   216                         command.run();
   214                    ranAction = true;
   217                     ranAction = true;
   215                    nextGeneration();
   218                     nextGeneration();
   216                    return 0;
   219                     return 0;
   217                } finally {
   220                 } finally {
   218                    if (!ranAction)
   221                     if (!ranAction)
   219                        breakBarrier();
   222                         breakBarrier();
   220                }
   223                 }
   221            }
   224             }
   222 
   225 
   223             // loop until tripped, broken, interrupted, or timed out
   226             // loop until tripped, broken, interrupted, or timed out
   224             for (;;) {
   227             for (;;) {
   225                 try {
   228                 try {
   226                     if (!timed)
   229                     if (!timed)
   352      */
   355      */
   353     public int await() throws InterruptedException, BrokenBarrierException {
   356     public int await() throws InterruptedException, BrokenBarrierException {
   354         try {
   357         try {
   355             return dowait(false, 0L);
   358             return dowait(false, 0L);
   356         } catch (TimeoutException toe) {
   359         } catch (TimeoutException toe) {
   357             throw new Error(toe); // cannot happen;
   360             throw new Error(toe); // cannot happen
   358         }
   361         }
   359     }
   362     }
   360 
   363 
   361     /**
   364     /**
   362      * Waits until all {@linkplain #getParties parties} have invoked
   365      * Waits until all {@linkplain #getParties parties} have invoked