--- jsr166/src/jsr166y/Phaser.java 2009/08/24 12:49:39 1.40 +++ jsr166/src/jsr166y/Phaser.java 2009/08/25 16:50:24 1.45 @@ -100,12 +100,11 @@ import java.util.concurrent.locks.LockSu * #getRegisteredParties} parties in total, of which {@link * #getArrivedParties} have arrived at the current phase ({@link * #getPhase}). When the remaining ({@link #getUnarrivedParties}) - * parties arrive, the phase advances; thus, this value is always - * greater than zero if there are any registered parties. The values - * returned by these methods may reflect transient states and so are - * not in general useful for synchronization control. Method {@link - * #toString} returns snapshots of these state queries in a form - * convenient for informal monitoring. + * parties arrive, the phase advances. The values returned by these + * methods may reflect transient states and so are not in general + * useful for synchronization control. Method {@link #toString} + * returns snapshots of these state queries in a form convenient for + * informal monitoring. * *
Sample usages: * @@ -143,14 +142,14 @@ import java.util.concurrent.locks.LockSu * } * }; * 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(); * } @@ -159,49 +158,45 @@ import java.util.concurrent.locks.LockSu * * If the main task must later await termination, it * may re-register and then execute a similar loop: - *
{@code + ** - * Related constructions may be used to await particular phase numbers + *{@code * // ... * phaser.register(); * while (!phaser.isTerminated()) - * phaser.arriveAndAwaitAdvance(); - * }+ * 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(); + ** * *{@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 @@ -250,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; @@ -764,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 @@ -778,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