--- jsr166/src/jsr166y/Phaser.java 2009/07/23 19:25:45 1.17 +++ jsr166/src/jsr166y/Phaser.java 2009/08/08 19:36:52 1.27 @@ -7,10 +7,9 @@ package jsr166y; import java.util.concurrent.*; -import java.util.concurrent.atomic.*; + +import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.LockSupport; -import sun.misc.Unsafe; -import java.lang.reflect.*; /** * A reusable synchronization barrier, similar in functionality to a @@ -33,40 +32,40 @@ import java.lang.reflect.*; * zero, and advancing when all parties reach the barrier (wrapping * around to zero after reaching {@code Integer.MAX_VALUE}). * - *
Sample usages: * - *
A Phaser may be used instead of a {@code CountDownLatch} to control - * a one-shot action serving a variable number of parties. The typical - * idiom is for the method setting this up to first register, then - * start the actions, then deregister, as in: + *
A {@code Phaser} may be used instead of a {@code CountDownLatch} + * to control a one-shot action serving a variable number of + * parties. The typical idiom is for the method setting this up to + * first register, then start the actions, then deregister, as in: * *
{@code * void runTasks(List* *list) { * final Phaser phaser = new Phaser(1); // "1" to register self + * // create and start threads * for (Runnable r : list) { * phaser.register(); * new Thread() { * public void run() { * phaser.arriveAndAwaitAdvance(); // await all creation * r.run(); - * phaser.arriveAndDeregister(); // signal completion * } * }.start(); * } * - * doSomethingOnBehalfOfWorkers(); - * phaser.arrive(); // allow threads to start - * int p = phaser.arriveAndDeregister(); // deregister self ... - * p = phaser.awaitAdvance(p); // ... and await arrival - * otherActions(); // do other things while tasks execute - * phaser.awaitAdvance(p); // await final completion + * // allow threads to start and deregister self + * phaser.arriveAndDeregister(); * }}
One way to cause a set of threads to repeatedly perform actions @@ -140,9 +137,9 @@ import java.lang.reflect.*; * phaser.arriveAndDeregister(); // deregister self, don't wait * }} * - *
To create a set of tasks using a tree of Phasers, + *
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 + * 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) { @@ -211,7 +208,7 @@ public class Phaser { private static final int phaseMask = 0x7fffffff; private static int unarrivedOf(long s) { - return (int)(s & ushortMask); + return (int) (s & ushortMask); } private static int partiesOf(long s) { @@ -250,7 +247,7 @@ public class Phaser { private final Phaser parent; /** - * The root of Phaser tree. Equals this if not in a tree. Used to + * The root of phaser tree. Equals this if not in a tree. Used to * support faster state push-down. */ private final Phaser root; @@ -266,7 +263,7 @@ public class Phaser { private final AtomicReferenceoddQ = new AtomicReference (); private AtomicReference queueFor(int phase) { - return (phase & 1) == 0? evenQ : oddQ; + return ((phase & 1) == 0) ? evenQ : oddQ; } /** @@ -274,7 +271,7 @@ public class Phaser { * root if necessary. */ private long getReconciledState() { - return parent == null? state : reconcileState(); + return (parent == null) ? state : reconcileState(); } /** @@ -301,16 +298,16 @@ public class Phaser { } /** - * Creates a new Phaser without any initially registered parties, + * Creates a new phaser without any initially registered parties, * initial phase number 0, and no parent. Any thread using this - * Phaser will need to first register for it. + * phaser will need to first register for it. */ public Phaser() { this(null); } /** - * Creates a new Phaser with the given numbers of registered + * Creates a new phaser with the given numbers of registered * unarrived parties, initial phase number 0, and no parent. * * @param parties the number of parties required to trip barrier @@ -322,7 +319,7 @@ public class Phaser { } /** - * Creates a new Phaser with the given parent, without any + * Creates a new phaser with the given parent, without any * initially registered parties. If parent is non-null this phaser * is registered with the parent and its initial phase number is * the same as that of parent phaser. @@ -342,7 +339,7 @@ public class Phaser { } /** - * Creates a new Phaser with the given parent and numbers of + * Creates a new phaser with the given parent and numbers of * registered unarrived parties. If parent is non-null, this phaser * is registered with the parent and its initial phase number is * the same as that of parent phaser. @@ -441,7 +438,7 @@ public class Phaser { if (par == null) { // directly trip if (casState (s, - trippedStateFor(onAdvance(phase, parties)? -1 : + trippedStateFor(onAdvance(phase, parties) ? -1 : ((phase + 1) & phaseMask), parties))) { releaseWaiters(phase); break; @@ -464,11 +461,12 @@ public class Phaser { } /** - * Arrives at the barrier, and deregisters from it, without - * waiting for others. Deregistration reduces number of parties + * Arrives at the barrier and deregisters from it without waiting + * for others. Deregistration reduces the number of parties * 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 is also deregistered from its parent. + * zero parties, this phaser also arrives at and is deregistered + * from its parent. * * @return the current barrier phase number upon entry to * this method, or a negative value if terminated @@ -502,7 +500,7 @@ public class Phaser { if (unarrived == 0) { if (casState (s, - trippedStateFor(onAdvance(phase, parties)? -1 : + trippedStateFor(onAdvance(phase, parties) ? -1 : ((phase + 1) & phaseMask), parties))) { releaseWaiters(phase); break; @@ -521,9 +519,11 @@ public class Phaser { /** * Arrives at the barrier and awaits others. Equivalent in effect - * to {@code awaitAdvance(arrive())}. If you instead need to - * await with interruption of timeout, and/or deregister upon - * arrival, you can arrange them using analogous constructions. + * to {@code awaitAdvance(arrive())}. If you need to await with + * 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}. * * @return the phase on entry to this method * @throws IllegalStateException if not terminated and the number @@ -534,9 +534,10 @@ public class Phaser { } /** - * Awaits the phase of the barrier to advance from the given - * value, or returns immediately if argument is negative or this - * barrier is terminated. + * Awaits the phase of the barrier to advance from the given phase + * value, or returns immediately if current phase of the barrier + * is not equal to the given phase value or this barrier is + * terminated. * * @param phase the phase on entry to this method * @return the phase on exit from this method @@ -587,7 +588,8 @@ public class Phaser { * @throws InterruptedException if thread interrupted while waiting * @throws TimeoutException if timed out while waiting */ - public int awaitAdvanceInterruptibly(int phase, long timeout, TimeUnit unit) + public int awaitAdvanceInterruptibly(int phase, + long timeout, TimeUnit unit) throws InterruptedException, TimeoutException { if (phase < 0) return phase; @@ -636,16 +638,6 @@ public class Phaser { } /** - * Returns {@code true} if the current phase number equals the given phase. - * - * @param phase the phase - * @return {@code true} if the current phase number equals the given phase - */ - public final boolean hasPhase(int phase) { - return phaseOf(getReconciledState()) == phase; - } - - /** * Returns the number of parties registered at this barrier. * * @return the number of parties @@ -675,9 +667,9 @@ public class Phaser { } /** - * Returns the parent of this phaser, or null if none. + * Returns the parent of this phaser, or {@code null} if none. * - * @return the parent of this phaser, or null if none + * @return the parent of this phaser, or {@code null} if none */ public Phaser getParent() { return parent; @@ -706,26 +698,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 true, then, rather than advance the - * phase number, this barrier will be set to a final termination - * state, and subsequent calls to {@code isTerminated} will - * return true. + * 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. * - * The default version returns true when the number of + *
The default version returns {@code true} when the number of * registered parties is zero. Normally, overrides that arrange * termination for other reasons should also preserve this * property. * - *
You may override this method to perform an action with side + *
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 {@code awaitAdvance} at each phase. - * Otherwise, you cannot ensure lack of interference. In - * particular, this method may be invoked more than once per - * transition if other parties successfully register while the - * invocation of this method is in progress, thus postponing the - * transition until those parties also arrive, re-triggering this - * method. + * before any arrive, and all {@link #awaitAdvance} at each phase. + * Otherwise, you cannot ensure lack of interference from other + * parties during the the invocation of this method. * * @param phase the phase number on entering the barrier * @param registeredParties the current number of registered parties @@ -930,49 +918,52 @@ public class Phaser { return p; } - // Temporary Unsafe mechanics for preliminary release - private static Unsafe getUnsafe() throws Throwable { - try { - return Unsafe.getUnsafe(); - } catch (SecurityException se) { - try { - return java.security.AccessController.doPrivileged - (new java.security.PrivilegedExceptionAction
() { - public Unsafe run() throws Exception { - return getUnsafePrivileged(); - }}); - } catch (java.security.PrivilegedActionException e) { - throw e.getCause(); - } - } - } + // Unsafe mechanics - private static Unsafe getUnsafePrivileged() - throws NoSuchFieldException, IllegalAccessException { - Field f = Unsafe.class.getDeclaredField("theUnsafe"); - f.setAccessible(true); - return (Unsafe) f.get(null); - } + private static final sun.misc.Unsafe UNSAFE = getUnsafe(); + private static final long stateOffset = + objectFieldOffset("state", Phaser.class); - private static long fieldOffset(String fieldName) - throws NoSuchFieldException { - return UNSAFE.objectFieldOffset - (Phaser.class.getDeclaredField(fieldName)); + private final boolean casState(long cmp, long val) { + return UNSAFE.compareAndSwapLong(this, stateOffset, cmp, val); } - static final Unsafe UNSAFE; - static final long stateOffset; - - static { + private static long objectFieldOffset(String field, Class> klazz) { try { - UNSAFE = getUnsafe(); - stateOffset = fieldOffset("state"); - } catch (Throwable e) { - throw new RuntimeException("Could not initialize intrinsics", e); + return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field)); + } catch (NoSuchFieldException e) { + // Convert Exception to corresponding Error + NoSuchFieldError error = new NoSuchFieldError(field); + error.initCause(e); + throw error; } } - final boolean casState(long cmp, long val) { - return UNSAFE.compareAndSwapLong(this, stateOffset, cmp, val); + /** + * Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package. + * Replace with a simple call to Unsafe.getUnsafe when integrating + * into a jdk. + * + * @return a sun.misc.Unsafe + */ + private static sun.misc.Unsafe getUnsafe() { + try { + return sun.misc.Unsafe.getUnsafe(); + } catch (SecurityException se) { + try { + return java.security.AccessController.doPrivileged + (new java.security + .PrivilegedExceptionAction () { + public sun.misc.Unsafe run() throws Exception { + java.lang.reflect.Field f = sun.misc + .Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + return (sun.misc.Unsafe) f.get(null); + }}); + } catch (java.security.PrivilegedActionException e) { + throw new RuntimeException("Could not initialize intrinsics", + e.getCause()); + } + } } }