--- jsr166/src/jsr166e/StampedLock.java 2012/10/15 12:12:42 1.19 +++ jsr166/src/jsr166e/StampedLock.java 2013/01/14 19:00:01 1.27 @@ -63,7 +63,7 @@ import java.util.concurrent.TimeUnit; * *

StampedLocks are designed for use as internal utilities in the * development of thread-safe components. Their use relies on - * knowledge of the internal properties of the the data, objects, and + * knowledge of the internal properties of the data, objects, and * methods they are protecting. They are not reentrant, so locked * bodies should not call other unknown methods that may try to * re-acquire locks (although you may pass a stamp to other methods @@ -125,16 +125,17 @@ import java.util.concurrent.TimeUnit; * } * * double distanceFromOriginV2() { // combines code paths + * double currentX = 0.0, currentY = 0.0; * for (long stamp = sl.tryOptimisticRead(); ; stamp = sl.readLock()) { - * double currentX = 0.0, currentY = 0.0; * try { * currentX = x; * currentY = y; * } finally { * if (sl.tryConvertToOptimisticRead(stamp) != 0L) // unlock or validate - * return Math.sqrt(currentX * currentX + currentY * currentY); + * break; * } * } + * return Math.sqrt(currentX * currentX + currentY * currentY); * } * * void moveIfAtOrigin(double newX, double newY) { // upgrade @@ -155,7 +156,7 @@ import java.util.concurrent.TimeUnit; * } * } * } finally { - * sl.unlock(stamp); + * sl.unlock(stamp); * } * } * }} @@ -225,7 +226,7 @@ public class StampedLock implements java * threads. Both await methods use a similar spin strategy: If * the associated queue appears to be empty, then the thread * spin-waits up to SPINS times (where each iteration decreases - * spin count with 50% probablility) before enqueing, and then, if + * spin count with 50% probability) before enqueuing, and then, if * it is the first thread to be enqueued, spins again up to SPINS * times before blocking. If, upon wakening it fails to obtain * lock, and is still (or becomes) the first waiting thread (which @@ -251,6 +252,8 @@ public class StampedLock implements java * be subject to future improvements. */ + private static final long serialVersionUID = -6001602636862214147L; + /** Number of processors, for spin control */ private static final int NCPU = Runtime.getRuntime().availableProcessors(); @@ -994,7 +997,7 @@ public class StampedLock implements java else if ((time = deadline - System.nanoTime()) <= 0L) return cancelWriter(node, false); if (node.prev == p && p.status == WAITING && - (p != whead || (state & WBIT) != 0L)) // recheck + (p != whead || (state & ABITS) != 0L)) // recheck U.park(false, time); if (interruptible && Thread.interrupted()) return cancelWriter(node, true); @@ -1007,9 +1010,9 @@ public class StampedLock implements java /** * If node non-null, forces cancel status and unsplices from queue * if possible. This is a variant of cancellation methods in - * AbstractQueuedSynchronizer (see its detailed explanation in + * AbstractQueuedSynchronizer (see its detailed explanation in AQS * internal documentation) that more conservatively wakes up other - * threads that may have had their links changed so as to preserve + * threads that may have had their links changed, so as to preserve * liveness in the main signalling methods. */ private long cancelWriter(WNode node, boolean interrupted) { @@ -1203,22 +1206,23 @@ public class StampedLock implements java 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()); - } + } catch (SecurityException tryReflectionInstead) {} + try { + return java.security.AccessController.doPrivileged + (new java.security.PrivilegedExceptionAction() { + public sun.misc.Unsafe run() throws Exception { + Class k = sun.misc.Unsafe.class; + for (java.lang.reflect.Field f : k.getDeclaredFields()) { + f.setAccessible(true); + Object x = f.get(null); + if (k.isInstance(x)) + return k.cast(x); + } + throw new NoSuchFieldError("the Unsafe"); + }}); + } catch (java.security.PrivilegedActionException e) { + throw new RuntimeException("Could not initialize intrinsics", + e.getCause()); } } - }