--- jsr166/src/jsr166y/Phaser.java 2009/08/23 20:12:24 1.36 +++ jsr166/src/jsr166y/Phaser.java 2009/08/25 16:50:24 1.45 @@ -12,94 +12,100 @@ import java.util.concurrent.atomic.Atomi import java.util.concurrent.locks.LockSupport; /** - * A reusable synchronization barrier, similar in functionality to a + * A reusable synchronization barrier, similar in functionality to * {@link java.util.concurrent.CyclicBarrier CyclicBarrier} and * {@link java.util.concurrent.CountDownLatch CountDownLatch} * but supporting more flexible usage. * - * - * *

Sample usages: * *

A {@code Phaser} may be used instead of a {@code CountDownLatch} @@ -131,43 +137,66 @@ import java.util.concurrent.locks.LockSu *

 {@code
  * void startTasks(List tasks, final int iterations) {
  *   final Phaser phaser = new Phaser() {
- *     public boolean onAdvance(int phase, int registeredParties) {
+ *     protected boolean onAdvance(int phase, int registeredParties) {
  *       return phase >= iterations || registeredParties == 0;
  *     }
  *   };
  *   phaser.register();
- *   for (Runnable task : tasks) {
+ *   for (final Runnable task : tasks) {
  *     phaser.register();
  *     new Thread() {
  *       public void run() {
  *         do {
  *           task.run();
  *           phaser.arriveAndAwaitAdvance();
- *         } while(!phaser.isTerminated();
+ *         } while (!phaser.isTerminated());
  *       }
  *     }.start();
  *   }
  *   phaser.arriveAndDeregister(); // deregister self, don't wait
  * }}
* + * If the main task must later await termination, it + * may re-register and then execute a similar loop: + *
 {@code
+ *   // ...
+ *   phaser.register();
+ *   while (!phaser.isTerminated())
+ *     phaser.arriveAndAwaitAdvance();}
+ * + *

Related constructions may be used to await particular phase numbers + * in contexts where you are sure that the phase will never wrap around + * {@code Integer.MAX_VALUE}. For example: + * + *

 {@code
+ * void awaitPhase(Phaser phaser, int phase) {
+ *   int p = phaser.register(); // assumes caller not already registered
+ *   while (p < phase) {
+ *     if (phaser.isTerminated())
+ *       // ... deal with unexpected termination
+ *     else
+ *       p = phaser.arriveAndAwaitAdvance();
+ *   }
+ *   phaser.arriveAndDeregister();
+ * }}
+ * + * *

To create a set of tasks using a tree of phasers, * you could use code of the following form, assuming a * Task class with a constructor accepting a phaser that * it registers for upon construction: + * *

 {@code
- * void build(Task[] actions, int lo, int hi, Phaser b) {
- *   int step = (hi - lo) / TASKS_PER_PHASER;
- *   if (step > 1) {
- *     int i = lo;
- *     while (i < hi) {
- *       int r = Math.min(i + step, hi);
- *       build(actions, i, r, new Phaser(b));
- *       i = r;
+ * void build(Task[] actions, int lo, int hi, Phaser ph) {
+ *   if (hi - lo > TASKS_PER_PHASER) {
+ *     for (int i = lo; i < hi; i += TASKS_PER_PHASER) {
+ *       int j = Math.min(i + TASKS_PER_PHASER, hi);
+ *       build(actions, i, j, new Phaser(ph));
  *     }
  *   } else {
  *     for (int i = lo; i < hi; ++i)
- *       actions[i] = new Task(b);
- *       // assumes new Task(b) performs b.register()
+ *       actions[i] = new Task(ph);
+ *       // assumes new Task(ph) performs ph.register()
  *   }
  * }
  * // .. initially called, for n tasks via
@@ -216,7 +245,6 @@ public class Phaser {
      */
     private volatile long state;
 
-    private static final int ushortBits = 16;
     private static final int ushortMask = 0xffff;
     private static final int phaseMask  = 0x7fffffff;
 
@@ -426,7 +454,9 @@ public class Phaser {
 
     /**
      * Arrives at the barrier, but does not wait for others.  (You can
-     * in turn wait for others via {@link #awaitAdvance}).
+     * in turn wait for others via {@link #awaitAdvance}).  It is an
+     * unenforced usage error for an unregistered party to invoke this
+     * method.
      *
      * @return the arrival phase number, or a negative value if terminated
      * @throws IllegalStateException if not terminated and the number
@@ -478,7 +508,8 @@ public class Phaser {
      * required to trip the barrier in future phases.  If this phaser
      * has a parent, and deregistration causes this phaser to have
      * zero parties, this phaser also arrives at and is deregistered
-     * from its parent.
+     * from its parent.  It is an unenforced usage error for an
+     * unregistered party to invoke this method.
      *
      * @return the arrival phase number, or a negative value if terminated
      * @throws IllegalStateException if not terminated and the number
@@ -534,7 +565,8 @@ public class Phaser {
      * interruption or timeout, you can arrange this with an analogous
      * construction using one of the other forms of the awaitAdvance
      * method.  If instead you need to deregister upon arrival use
-     * {@code arriveAndDeregister}.
+     * {@code arriveAndDeregister}. It is an unenforced usage error
+     * for an unregistered party to invoke this method.
      *
      * @return the arrival phase number, or a negative number if terminated
      * @throws IllegalStateException if not terminated and the number
@@ -548,7 +580,8 @@ public class Phaser {
      * Awaits the phase of the barrier to advance from the given phase
      * value, returning immediately if the current phase of the
      * barrier is not equal to the given phase value or this barrier
-     * is terminated.
+     * is terminated.  It is an unenforced usage error for an
+     * unregistered party to invoke this method.
      *
      * @param phase an arrival phase number, or negative value if
      * terminated; this argument is normally the value returned by a
@@ -571,10 +604,11 @@ public class Phaser {
 
     /**
      * Awaits the phase of the barrier to advance from the given phase
-     * value, throwing {@code InterruptedException} if interrupted while
-     * waiting, or returning immediately if the current phase of the
-     * barrier is not equal to the given phase value or this barrier
-     * is terminated.
+     * value, throwing {@code InterruptedException} if interrupted
+     * while waiting, or returning immediately if the current phase of
+     * the barrier is not equal to the given phase value or this
+     * barrier is terminated. It is an unenforced usage error for an
+     * unregistered party to invoke this method.
      *
      * @param phase an arrival phase number, or negative value if
      * terminated; this argument is normally the value returned by a
@@ -598,10 +632,12 @@ public class Phaser {
 
     /**
      * Awaits the phase of the barrier to advance from the given phase
-     * value or the given timeout to elapse, throwing
-     * {@code InterruptedException} if interrupted while waiting, or
-     * returning immediately if the current phase of the barrier is not
-     * equal to the given phase value or this barrier is terminated.
+     * value or the given timeout to elapse, throwing {@code
+     * InterruptedException} if interrupted while waiting, or
+     * returning immediately if the current phase of the barrier is
+     * not equal to the given phase value or this barrier is
+     * terminated.  It is an unenforced usage error for an
+     * unregistered party to invoke this method.
      *
      * @param phase an arrival phase number, or negative value if
      * terminated; this argument is normally the value returned by a
@@ -722,13 +758,22 @@ public class Phaser {
     }
 
     /**
-     * Overridable method to perform an action upon phase advance, and
-     * to control termination. This method is invoked whenever the
-     * barrier is tripped (and thus all other waiting parties are
-     * dormant). If it returns {@code true}, then, rather than advance
-     * the phase number, this barrier will be set to a final
-     * termination state, and subsequent calls to {@link #isTerminated}
-     * will return true.
+     * Overridable method to perform an action upon impending phase
+     * advance, and to control termination. This method is invoked
+     * upon arrival of the party tripping the barrier (when all other
+     * waiting parties are dormant).  If this method returns {@code
+     * true}, then, rather than advance the phase number, this barrier
+     * will be set to a final termination state, and subsequent calls
+     * to {@link #isTerminated} will return true. Any (unchecked)
+     * Exception or Error thrown by an invocation of this method is
+     * propagated to the party attempting to trip the barrier, in
+     * which case no advance occurs.
+     *
+     * 

The arguments to this method provide the state of the phaser + * prevailing for the current transition. (When called from within + * an implementation of {@code onAdvance} the values returned by + * methods such as {@code getPhase} may or may not reliably + * indicate the state to which this transition applies.) * *

The default version returns {@code true} when the number of * registered parties is zero. Normally, overrides that arrange @@ -736,11 +781,12 @@ public class Phaser { * property. * *

You may override this method to perform an action with side - * effects visible to participating tasks, but it is in general - * only sensible to do so in designs where all parties register - * before any arrive, and all {@link #awaitAdvance} at each phase. - * Otherwise, you cannot ensure lack of interference from other - * parties during the invocation of this method. + * effects visible to participating tasks, but doing so requires + * care: Method {@code onAdvance} may be invoked more than once + * per transition. Further, unless all parties register before + * any arrive, and all {@link #awaitAdvance} at each phase, then + * you cannot ensure lack of interference from other parties + * during the invocation of this method. * * @param phase the phase number on entering the barrier * @param registeredParties the current number of registered parties