# HG changeset patch # User dl # Date 1443541469 -3600 # Node ID caeef2c79243c6baac9e8f1610e5337a18a79818 # Parent e331a1a5a6212aaf90f7d731659366193454c8de 8134854: Bulk integration of java.util.concurrent.atomic classes Reviewed-by: martin, psandoz, chegar diff -r e331a1a5a621 -r caeef2c79243 jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java Tue Sep 29 18:01:33 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java Tue Sep 29 16:44:29 2015 +0100 @@ -34,7 +34,6 @@ */ package java.util.concurrent.atomic; -import sun.misc.Unsafe; /** * A {@code boolean} value that may be updated atomically. See the @@ -49,15 +48,17 @@ */ public class AtomicBoolean implements java.io.Serializable { private static final long serialVersionUID = 4654671469794556979L; - // setup to use Unsafe.compareAndSwapInt for updates - private static final Unsafe unsafe = Unsafe.getUnsafe(); - private static final long valueOffset; + + private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); + private static final long VALUE; static { try { - valueOffset = unsafe.objectFieldOffset + VALUE = U.objectFieldOffset (AtomicBoolean.class.getDeclaredField("value")); - } catch (Exception ex) { throw new Error(ex); } + } catch (ReflectiveOperationException e) { + throw new Error(e); + } } private volatile int value; @@ -96,9 +97,9 @@ * the actual value was not equal to the expected value. */ public final boolean compareAndSet(boolean expect, boolean update) { - int e = expect ? 1 : 0; - int u = update ? 1 : 0; - return unsafe.compareAndSwapInt(this, valueOffset, e, u); + return U.compareAndSwapInt(this, VALUE, + (expect ? 1 : 0), + (update ? 1 : 0)); } /** @@ -114,9 +115,9 @@ * @return {@code true} if successful */ public boolean weakCompareAndSet(boolean expect, boolean update) { - int e = expect ? 1 : 0; - int u = update ? 1 : 0; - return unsafe.compareAndSwapInt(this, valueOffset, e, u); + return U.compareAndSwapInt(this, VALUE, + (expect ? 1 : 0), + (update ? 1 : 0)); } /** @@ -135,8 +136,7 @@ * @since 1.6 */ public final void lazySet(boolean newValue) { - int v = newValue ? 1 : 0; - unsafe.putOrderedInt(this, valueOffset, v); + U.putOrderedInt(this, VALUE, (newValue ? 1 : 0)); } /** diff -r e331a1a5a621 -r caeef2c79243 jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java Tue Sep 29 18:01:33 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java Tue Sep 29 16:44:29 2015 +0100 @@ -34,9 +34,9 @@ */ package java.util.concurrent.atomic; -import java.util.function.IntUnaryOperator; + import java.util.function.IntBinaryOperator; -import sun.misc.Unsafe; +import java.util.function.IntUnaryOperator; /** * An {@code int} value that may be updated atomically. See the @@ -50,19 +50,20 @@ * * @since 1.5 * @author Doug Lea -*/ + */ public class AtomicInteger extends Number implements java.io.Serializable { private static final long serialVersionUID = 6214790243416807050L; - // setup to use Unsafe.compareAndSwapInt for updates - private static final Unsafe unsafe = Unsafe.getUnsafe(); - private static final long valueOffset; + private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); + private static final long VALUE; static { try { - valueOffset = unsafe.objectFieldOffset + VALUE = U.objectFieldOffset (AtomicInteger.class.getDeclaredField("value")); - } catch (Exception ex) { throw new Error(ex); } + } catch (ReflectiveOperationException e) { + throw new Error(e); + } } private volatile int value; @@ -107,7 +108,7 @@ * @since 1.6 */ public final void lazySet(int newValue) { - unsafe.putOrderedInt(this, valueOffset, newValue); + U.putOrderedInt(this, VALUE, newValue); } /** @@ -117,7 +118,7 @@ * @return the previous value */ public final int getAndSet(int newValue) { - return unsafe.getAndSetInt(this, valueOffset, newValue); + return U.getAndSetInt(this, VALUE, newValue); } /** @@ -130,7 +131,7 @@ * the actual value was not equal to the expected value. */ public final boolean compareAndSet(int expect, int update) { - return unsafe.compareAndSwapInt(this, valueOffset, expect, update); + return U.compareAndSwapInt(this, VALUE, expect, update); } /** @@ -146,7 +147,7 @@ * @return {@code true} if successful */ public final boolean weakCompareAndSet(int expect, int update) { - return unsafe.compareAndSwapInt(this, valueOffset, expect, update); + return U.compareAndSwapInt(this, VALUE, expect, update); } /** @@ -155,7 +156,7 @@ * @return the previous value */ public final int getAndIncrement() { - return unsafe.getAndAddInt(this, valueOffset, 1); + return U.getAndAddInt(this, VALUE, 1); } /** @@ -164,7 +165,7 @@ * @return the previous value */ public final int getAndDecrement() { - return unsafe.getAndAddInt(this, valueOffset, -1); + return U.getAndAddInt(this, VALUE, -1); } /** @@ -174,7 +175,7 @@ * @return the previous value */ public final int getAndAdd(int delta) { - return unsafe.getAndAddInt(this, valueOffset, delta); + return U.getAndAddInt(this, VALUE, delta); } /** @@ -183,7 +184,7 @@ * @return the updated value */ public final int incrementAndGet() { - return unsafe.getAndAddInt(this, valueOffset, 1) + 1; + return U.getAndAddInt(this, VALUE, 1) + 1; } /** @@ -192,7 +193,7 @@ * @return the updated value */ public final int decrementAndGet() { - return unsafe.getAndAddInt(this, valueOffset, -1) - 1; + return U.getAndAddInt(this, VALUE, -1) - 1; } /** @@ -202,7 +203,7 @@ * @return the updated value */ public final int addAndGet(int delta) { - return unsafe.getAndAddInt(this, valueOffset, delta) + delta; + return U.getAndAddInt(this, VALUE, delta) + delta; } /** @@ -301,6 +302,7 @@ /** * Returns the value of this {@code AtomicInteger} as an {@code int}. + * Equivalent to {@link #get()}. */ public int intValue() { return get(); diff -r e331a1a5a621 -r caeef2c79243 jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java Tue Sep 29 18:01:33 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java Tue Sep 29 16:44:29 2015 +0100 @@ -34,9 +34,9 @@ */ package java.util.concurrent.atomic; -import java.util.function.IntUnaryOperator; + import java.util.function.IntBinaryOperator; -import sun.misc.Unsafe; +import java.util.function.IntUnaryOperator; /** * An {@code int} array in which elements may be updated atomically. @@ -49,16 +49,17 @@ public class AtomicIntegerArray implements java.io.Serializable { private static final long serialVersionUID = 2862133569453604235L; - private static final Unsafe unsafe = Unsafe.getUnsafe(); - private static final int base = unsafe.arrayBaseOffset(int[].class); - private static final int shift; + private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); + private static final int ABASE; + private static final int ASHIFT; private final int[] array; static { - int scale = unsafe.arrayIndexScale(int[].class); + ABASE = U.arrayBaseOffset(int[].class); + int scale = U.arrayIndexScale(int[].class); if ((scale & (scale - 1)) != 0) - throw new Error("data type scale not a power of two"); - shift = 31 - Integer.numberOfLeadingZeros(scale); + throw new Error("array index scale not a power of two"); + ASHIFT = 31 - Integer.numberOfLeadingZeros(scale); } private long checkedByteOffset(int i) { @@ -69,7 +70,7 @@ } private static long byteOffset(int i) { - return ((long) i << shift) + base; + return ((long) i << ASHIFT) + ABASE; } /** @@ -114,7 +115,7 @@ } private int getRaw(long offset) { - return unsafe.getIntVolatile(array, offset); + return U.getIntVolatile(array, offset); } /** @@ -124,7 +125,7 @@ * @param newValue the new value */ public final void set(int i, int newValue) { - unsafe.putIntVolatile(array, checkedByteOffset(i), newValue); + U.putIntVolatile(array, checkedByteOffset(i), newValue); } /** @@ -135,7 +136,7 @@ * @since 1.6 */ public final void lazySet(int i, int newValue) { - unsafe.putOrderedInt(array, checkedByteOffset(i), newValue); + U.putOrderedInt(array, checkedByteOffset(i), newValue); } /** @@ -147,7 +148,7 @@ * @return the previous value */ public final int getAndSet(int i, int newValue) { - return unsafe.getAndSetInt(array, checkedByteOffset(i), newValue); + return U.getAndSetInt(array, checkedByteOffset(i), newValue); } /** @@ -165,7 +166,7 @@ } private boolean compareAndSetRaw(long offset, int expect, int update) { - return unsafe.compareAndSwapInt(array, offset, expect, update); + return U.compareAndSwapInt(array, offset, expect, update); } /** @@ -213,7 +214,7 @@ * @return the previous value */ public final int getAndAdd(int i, int delta) { - return unsafe.getAndAddInt(array, checkedByteOffset(i), delta); + return U.getAndAddInt(array, checkedByteOffset(i), delta); } /** @@ -247,7 +248,6 @@ return getAndAdd(i, delta) + delta; } - /** * Atomically updates the element at index {@code i} with the results * of applying the given function, returning the previous value. The diff -r e331a1a5a621 -r caeef2c79243 jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java Tue Sep 29 18:01:33 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java Tue Sep 29 16:44:29 2015 +0100 @@ -34,14 +34,14 @@ */ package java.util.concurrent.atomic; -import java.util.function.IntUnaryOperator; -import java.util.function.IntBinaryOperator; -import sun.misc.Unsafe; + import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.security.AccessController; +import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; -import java.security.PrivilegedActionException; +import java.util.function.IntBinaryOperator; +import java.util.function.IntUnaryOperator; import sun.reflect.CallerSensitive; import sun.reflect.Reflection; @@ -363,11 +363,11 @@ } /** - * Standard hotspot implementation using intrinsics + * Standard hotspot implementation using intrinsics. */ private static class AtomicIntegerFieldUpdaterImpl extends AtomicIntegerFieldUpdater { - private static final Unsafe unsafe = Unsafe.getUnsafe(); + private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); private final long offset; private final Class tclass; private final Class cclass; @@ -391,7 +391,7 @@ ClassLoader ccl = caller.getClassLoader(); if ((ccl != null) && (ccl != cl) && ((cl == null) || !isAncestor(cl, ccl))) { - sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); + sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); } } catch (PrivilegedActionException pae) { throw new RuntimeException(pae.getException()); @@ -409,7 +409,7 @@ this.cclass = (Modifier.isProtected(modifiers) && caller != tclass) ? caller : null; this.tclass = tclass; - offset = unsafe.objectFieldOffset(field); + offset = U.objectFieldOffset(field); } /** @@ -437,32 +437,32 @@ public boolean compareAndSet(T obj, int expect, int update) { if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.compareAndSwapInt(obj, offset, expect, update); + return U.compareAndSwapInt(obj, offset, expect, update); } public boolean weakCompareAndSet(T obj, int expect, int update) { if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.compareAndSwapInt(obj, offset, expect, update); + return U.compareAndSwapInt(obj, offset, expect, update); } public void set(T obj, int newValue) { if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - unsafe.putIntVolatile(obj, offset, newValue); + U.putIntVolatile(obj, offset, newValue); } public void lazySet(T obj, int newValue) { if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - unsafe.putOrderedInt(obj, offset, newValue); + U.putOrderedInt(obj, offset, newValue); } public final int get(T obj) { if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.getIntVolatile(obj, offset); + return U.getIntVolatile(obj, offset); } public int getAndSet(T obj, int newValue) { if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.getAndSetInt(obj, offset, newValue); + return U.getAndSetInt(obj, offset, newValue); } public int getAndIncrement(T obj) { @@ -475,7 +475,7 @@ public int getAndAdd(T obj, int delta) { if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.getAndAddInt(obj, offset, delta); + return U.getAndAddInt(obj, offset, delta); } public int incrementAndGet(T obj) { @@ -483,7 +483,7 @@ } public int decrementAndGet(T obj) { - return getAndAdd(obj, -1) - 1; + return getAndAdd(obj, -1) - 1; } public int addAndGet(T obj, int delta) { diff -r e331a1a5a621 -r caeef2c79243 jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java Tue Sep 29 18:01:33 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java Tue Sep 29 16:44:29 2015 +0100 @@ -34,9 +34,9 @@ */ package java.util.concurrent.atomic; -import java.util.function.LongUnaryOperator; + import java.util.function.LongBinaryOperator; -import sun.misc.Unsafe; +import java.util.function.LongUnaryOperator; /** * A {@code long} value that may be updated atomically. See the @@ -54,9 +54,8 @@ public class AtomicLong extends Number implements java.io.Serializable { private static final long serialVersionUID = 1927816293512124184L; - // setup to use Unsafe.compareAndSwapLong for updates - private static final Unsafe unsafe = Unsafe.getUnsafe(); - private static final long valueOffset; + private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); + private static final long VALUE; /** * Records whether the underlying JVM supports lockless @@ -74,9 +73,11 @@ static { try { - valueOffset = unsafe.objectFieldOffset + VALUE = U.objectFieldOffset (AtomicLong.class.getDeclaredField("value")); - } catch (Exception ex) { throw new Error(ex); } + } catch (ReflectiveOperationException e) { + throw new Error(e); + } } private volatile long value; @@ -111,7 +112,9 @@ * @param newValue the new value */ public final void set(long newValue) { - value = newValue; + // Use putLongVolatile instead of ordinary volatile store when + // using compareAndSwapLong, for sake of some 32bit systems. + U.putLongVolatile(this, VALUE, newValue); } /** @@ -121,7 +124,7 @@ * @since 1.6 */ public final void lazySet(long newValue) { - unsafe.putOrderedLong(this, valueOffset, newValue); + U.putOrderedLong(this, VALUE, newValue); } /** @@ -131,7 +134,7 @@ * @return the previous value */ public final long getAndSet(long newValue) { - return unsafe.getAndSetLong(this, valueOffset, newValue); + return U.getAndSetLong(this, VALUE, newValue); } /** @@ -144,7 +147,7 @@ * the actual value was not equal to the expected value. */ public final boolean compareAndSet(long expect, long update) { - return unsafe.compareAndSwapLong(this, valueOffset, expect, update); + return U.compareAndSwapLong(this, VALUE, expect, update); } /** @@ -160,7 +163,7 @@ * @return {@code true} if successful */ public final boolean weakCompareAndSet(long expect, long update) { - return unsafe.compareAndSwapLong(this, valueOffset, expect, update); + return U.compareAndSwapLong(this, VALUE, expect, update); } /** @@ -169,7 +172,7 @@ * @return the previous value */ public final long getAndIncrement() { - return unsafe.getAndAddLong(this, valueOffset, 1L); + return U.getAndAddLong(this, VALUE, 1L); } /** @@ -178,7 +181,7 @@ * @return the previous value */ public final long getAndDecrement() { - return unsafe.getAndAddLong(this, valueOffset, -1L); + return U.getAndAddLong(this, VALUE, -1L); } /** @@ -188,7 +191,7 @@ * @return the previous value */ public final long getAndAdd(long delta) { - return unsafe.getAndAddLong(this, valueOffset, delta); + return U.getAndAddLong(this, VALUE, delta); } /** @@ -197,7 +200,7 @@ * @return the updated value */ public final long incrementAndGet() { - return unsafe.getAndAddLong(this, valueOffset, 1L) + 1L; + return U.getAndAddLong(this, VALUE, 1L) + 1L; } /** @@ -206,7 +209,7 @@ * @return the updated value */ public final long decrementAndGet() { - return unsafe.getAndAddLong(this, valueOffset, -1L) - 1L; + return U.getAndAddLong(this, VALUE, -1L) - 1L; } /** @@ -216,7 +219,7 @@ * @return the updated value */ public final long addAndGet(long delta) { - return unsafe.getAndAddLong(this, valueOffset, delta) + delta; + return U.getAndAddLong(this, VALUE, delta) + delta; } /** @@ -324,6 +327,7 @@ /** * Returns the value of this {@code AtomicLong} as a {@code long}. + * Equivalent to {@link #get()}. */ public long longValue() { return get(); diff -r e331a1a5a621 -r caeef2c79243 jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java Tue Sep 29 18:01:33 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java Tue Sep 29 16:44:29 2015 +0100 @@ -34,9 +34,9 @@ */ package java.util.concurrent.atomic; -import java.util.function.LongUnaryOperator; + import java.util.function.LongBinaryOperator; -import sun.misc.Unsafe; +import java.util.function.LongUnaryOperator; /** * A {@code long} array in which elements may be updated atomically. @@ -48,16 +48,17 @@ public class AtomicLongArray implements java.io.Serializable { private static final long serialVersionUID = -2308431214976778248L; - private static final Unsafe unsafe = Unsafe.getUnsafe(); - private static final int base = unsafe.arrayBaseOffset(long[].class); - private static final int shift; + private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); + private static final int ABASE; + private static final int ASHIFT; private final long[] array; static { - int scale = unsafe.arrayIndexScale(long[].class); + ABASE = U.arrayBaseOffset(long[].class); + int scale = U.arrayIndexScale(long[].class); if ((scale & (scale - 1)) != 0) - throw new Error("data type scale not a power of two"); - shift = 31 - Integer.numberOfLeadingZeros(scale); + throw new Error("array index scale not a power of two"); + ASHIFT = 31 - Integer.numberOfLeadingZeros(scale); } private long checkedByteOffset(int i) { @@ -68,7 +69,7 @@ } private static long byteOffset(int i) { - return ((long) i << shift) + base; + return ((long) i << ASHIFT) + ABASE; } /** @@ -113,7 +114,7 @@ } private long getRaw(long offset) { - return unsafe.getLongVolatile(array, offset); + return U.getLongVolatile(array, offset); } /** @@ -123,7 +124,7 @@ * @param newValue the new value */ public final void set(int i, long newValue) { - unsafe.putLongVolatile(array, checkedByteOffset(i), newValue); + U.putLongVolatile(array, checkedByteOffset(i), newValue); } /** @@ -134,7 +135,7 @@ * @since 1.6 */ public final void lazySet(int i, long newValue) { - unsafe.putOrderedLong(array, checkedByteOffset(i), newValue); + U.putOrderedLong(array, checkedByteOffset(i), newValue); } /** @@ -146,7 +147,7 @@ * @return the previous value */ public final long getAndSet(int i, long newValue) { - return unsafe.getAndSetLong(array, checkedByteOffset(i), newValue); + return U.getAndSetLong(array, checkedByteOffset(i), newValue); } /** @@ -164,7 +165,7 @@ } private boolean compareAndSetRaw(long offset, long expect, long update) { - return unsafe.compareAndSwapLong(array, offset, expect, update); + return U.compareAndSwapLong(array, offset, expect, update); } /** @@ -212,7 +213,7 @@ * @return the previous value */ public final long getAndAdd(int i, long delta) { - return unsafe.getAndAddLong(array, checkedByteOffset(i), delta); + return U.getAndAddLong(array, checkedByteOffset(i), delta); } /** diff -r e331a1a5a621 -r caeef2c79243 jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java Tue Sep 29 18:01:33 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java Tue Sep 29 16:44:29 2015 +0100 @@ -34,14 +34,14 @@ */ package java.util.concurrent.atomic; -import java.util.function.LongUnaryOperator; -import java.util.function.LongBinaryOperator; -import sun.misc.Unsafe; + import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.security.AccessController; +import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; -import java.security.PrivilegedActionException; +import java.util.function.LongBinaryOperator; +import java.util.function.LongUnaryOperator; import sun.reflect.CallerSensitive; import sun.reflect.Reflection; @@ -366,7 +366,7 @@ } private static class CASUpdater extends AtomicLongFieldUpdater { - private static final Unsafe unsafe = Unsafe.getUnsafe(); + private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); private final long offset; private final Class tclass; private final Class cclass; @@ -389,7 +389,7 @@ ClassLoader ccl = caller.getClassLoader(); if ((ccl != null) && (ccl != cl) && ((cl == null) || !isAncestor(cl, ccl))) { - sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); + sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); } } catch (PrivilegedActionException pae) { throw new RuntimeException(pae.getException()); @@ -407,7 +407,7 @@ this.cclass = (Modifier.isProtected(modifiers) && caller != tclass) ? caller : null; this.tclass = tclass; - offset = unsafe.objectFieldOffset(field); + offset = U.objectFieldOffset(field); } private void fullCheck(T obj) { @@ -419,32 +419,32 @@ public boolean compareAndSet(T obj, long expect, long update) { if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.compareAndSwapLong(obj, offset, expect, update); + return U.compareAndSwapLong(obj, offset, expect, update); } public boolean weakCompareAndSet(T obj, long expect, long update) { if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.compareAndSwapLong(obj, offset, expect, update); + return U.compareAndSwapLong(obj, offset, expect, update); } public void set(T obj, long newValue) { if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - unsafe.putLongVolatile(obj, offset, newValue); + U.putLongVolatile(obj, offset, newValue); } public void lazySet(T obj, long newValue) { if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - unsafe.putOrderedLong(obj, offset, newValue); + U.putOrderedLong(obj, offset, newValue); } public long get(T obj) { if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.getLongVolatile(obj, offset); + return U.getLongVolatile(obj, offset); } public long getAndSet(T obj, long newValue) { if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.getAndSetLong(obj, offset, newValue); + return U.getAndSetLong(obj, offset, newValue); } public long getAndIncrement(T obj) { @@ -457,7 +457,7 @@ public long getAndAdd(T obj, long delta) { if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); - return unsafe.getAndAddLong(obj, offset, delta); + return U.getAndAddLong(obj, offset, delta); } public long incrementAndGet(T obj) { @@ -465,7 +465,7 @@ } public long decrementAndGet(T obj) { - return getAndAdd(obj, -1) - 1; + return getAndAdd(obj, -1) - 1; } public long addAndGet(T obj, long delta) { @@ -490,7 +490,7 @@ private static class LockedUpdater extends AtomicLongFieldUpdater { - private static final Unsafe unsafe = Unsafe.getUnsafe(); + private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); private final long offset; private final Class tclass; private final Class cclass; @@ -513,7 +513,7 @@ ClassLoader ccl = caller.getClassLoader(); if ((ccl != null) && (ccl != cl) && ((cl == null) || !isAncestor(cl, ccl))) { - sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); + sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); } } catch (PrivilegedActionException pae) { throw new RuntimeException(pae.getException()); @@ -531,7 +531,7 @@ this.cclass = (Modifier.isProtected(modifiers) && caller != tclass) ? caller : null; this.tclass = tclass; - offset = unsafe.objectFieldOffset(field); + offset = U.objectFieldOffset(field); } private void fullCheck(T obj) { @@ -544,10 +544,10 @@ public boolean compareAndSet(T obj, long expect, long update) { if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); synchronized (this) { - long v = unsafe.getLong(obj, offset); + long v = U.getLong(obj, offset); if (v != expect) return false; - unsafe.putLong(obj, offset, update); + U.putLong(obj, offset, update); return true; } } @@ -559,7 +559,7 @@ public void set(T obj, long newValue) { if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); synchronized (this) { - unsafe.putLong(obj, offset, newValue); + U.putLong(obj, offset, newValue); } } @@ -570,7 +570,7 @@ public long get(T obj) { if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj); synchronized (this) { - return unsafe.getLong(obj, offset); + return U.getLong(obj, offset); } } @@ -595,7 +595,7 @@ * classloader's delegation chain. * Equivalent to the inaccessible: first.isAncestor(second). */ - private static boolean isAncestor(ClassLoader first, ClassLoader second) { + static boolean isAncestor(ClassLoader first, ClassLoader second) { ClassLoader acl = first; do { acl = acl.getParent(); diff -r e331a1a5a621 -r caeef2c79243 jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicMarkableReference.java --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicMarkableReference.java Tue Sep 29 18:01:33 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicMarkableReference.java Tue Sep 29 16:44:29 2015 +0100 @@ -97,7 +97,7 @@ * Typical usage is {@code boolean[1] holder; ref = v.get(holder); }. * * @param markHolder an array of size of at least one. On return, - * {@code markholder[0]} will hold the value of the mark. + * {@code markHolder[0]} will hold the value of the mark. * @return the current value of the reference */ public V get(boolean[] markHolder) { @@ -190,23 +190,18 @@ // Unsafe mechanics - private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe(); - private static final long pairOffset = - objectFieldOffset(UNSAFE, "pair", AtomicMarkableReference.class); - - private boolean casPair(Pair cmp, Pair val) { - return UNSAFE.compareAndSwapObject(this, pairOffset, cmp, val); + private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); + private static final long PAIR; + static { + try { + PAIR = U.objectFieldOffset + (AtomicMarkableReference.class.getDeclaredField("pair")); + } catch (ReflectiveOperationException e) { + throw new Error(e); + } } - static long objectFieldOffset(sun.misc.Unsafe UNSAFE, - String field, Class klazz) { - try { - return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field)); - } catch (NoSuchFieldException e) { - // Convert Exception to corresponding Error - NoSuchFieldError error = new NoSuchFieldError(field); - error.initCause(e); - throw error; - } + private boolean casPair(Pair cmp, Pair val) { + return U.compareAndSwapObject(this, PAIR, cmp, val); } } diff -r e331a1a5a621 -r caeef2c79243 jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java Tue Sep 29 18:01:33 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java Tue Sep 29 16:44:29 2015 +0100 @@ -34,9 +34,9 @@ */ package java.util.concurrent.atomic; -import java.util.function.UnaryOperator; + import java.util.function.BinaryOperator; -import sun.misc.Unsafe; +import java.util.function.UnaryOperator; /** * An object reference that may be updated atomically. See the {@link @@ -49,14 +49,16 @@ public class AtomicReference implements java.io.Serializable { private static final long serialVersionUID = -1848883965231344442L; - private static final Unsafe unsafe = Unsafe.getUnsafe(); - private static final long valueOffset; + private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); + private static final long VALUE; static { try { - valueOffset = unsafe.objectFieldOffset + VALUE = U.objectFieldOffset (AtomicReference.class.getDeclaredField("value")); - } catch (Exception ex) { throw new Error(ex); } + } catch (ReflectiveOperationException e) { + throw new Error(e); + } } private volatile V value; @@ -101,7 +103,7 @@ * @since 1.6 */ public final void lazySet(V newValue) { - unsafe.putOrderedObject(this, valueOffset, newValue); + U.putOrderedObject(this, VALUE, newValue); } /** @@ -113,7 +115,7 @@ * the actual value was not equal to the expected value. */ public final boolean compareAndSet(V expect, V update) { - return unsafe.compareAndSwapObject(this, valueOffset, expect, update); + return U.compareAndSwapObject(this, VALUE, expect, update); } /** @@ -129,7 +131,7 @@ * @return {@code true} if successful */ public final boolean weakCompareAndSet(V expect, V update) { - return unsafe.compareAndSwapObject(this, valueOffset, expect, update); + return U.compareAndSwapObject(this, VALUE, expect, update); } /** @@ -140,7 +142,7 @@ */ @SuppressWarnings("unchecked") public final V getAndSet(V newValue) { - return (V)unsafe.getAndSetObject(this, valueOffset, newValue); + return (V)U.getAndSetObject(this, VALUE, newValue); } /** diff -r e331a1a5a621 -r caeef2c79243 jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java Tue Sep 29 18:01:33 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java Tue Sep 29 16:44:29 2015 +0100 @@ -34,11 +34,11 @@ */ package java.util.concurrent.atomic; -import java.util.function.UnaryOperator; -import java.util.function.BinaryOperator; + +import java.lang.reflect.Array; import java.util.Arrays; -import java.lang.reflect.Array; -import sun.misc.Unsafe; +import java.util.function.BinaryOperator; +import java.util.function.UnaryOperator; /** * An array of object references in which elements may be updated @@ -52,23 +52,22 @@ public class AtomicReferenceArray implements java.io.Serializable { private static final long serialVersionUID = -6209656149925076980L; - private static final Unsafe unsafe; - private static final int base; - private static final int shift; - private static final long arrayFieldOffset; + private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); + private static final int ABASE; + private static final int ASHIFT; + private static final long ARRAY; private final Object[] array; // must have exact type Object[] static { try { - unsafe = Unsafe.getUnsafe(); - arrayFieldOffset = unsafe.objectFieldOffset + ARRAY = U.objectFieldOffset (AtomicReferenceArray.class.getDeclaredField("array")); - base = unsafe.arrayBaseOffset(Object[].class); - int scale = unsafe.arrayIndexScale(Object[].class); + ABASE = U.arrayBaseOffset(Object[].class); + int scale = U.arrayIndexScale(Object[].class); if ((scale & (scale - 1)) != 0) - throw new Error("data type scale not a power of two"); - shift = 31 - Integer.numberOfLeadingZeros(scale); - } catch (Exception e) { + throw new Error("array index scale not a power of two"); + ASHIFT = 31 - Integer.numberOfLeadingZeros(scale); + } catch (ReflectiveOperationException e) { throw new Error(e); } } @@ -81,7 +80,7 @@ } private static long byteOffset(int i) { - return ((long) i << shift) + base; + return ((long) i << ASHIFT) + ABASE; } /** @@ -127,7 +126,7 @@ @SuppressWarnings("unchecked") private E getRaw(long offset) { - return (E) unsafe.getObjectVolatile(array, offset); + return (E) U.getObjectVolatile(array, offset); } /** @@ -137,7 +136,7 @@ * @param newValue the new value */ public final void set(int i, E newValue) { - unsafe.putObjectVolatile(array, checkedByteOffset(i), newValue); + U.putObjectVolatile(array, checkedByteOffset(i), newValue); } /** @@ -148,7 +147,7 @@ * @since 1.6 */ public final void lazySet(int i, E newValue) { - unsafe.putOrderedObject(array, checkedByteOffset(i), newValue); + U.putOrderedObject(array, checkedByteOffset(i), newValue); } /** @@ -161,7 +160,7 @@ */ @SuppressWarnings("unchecked") public final E getAndSet(int i, E newValue) { - return (E)unsafe.getAndSetObject(array, checkedByteOffset(i), newValue); + return (E)U.getAndSetObject(array, checkedByteOffset(i), newValue); } /** @@ -179,7 +178,7 @@ } private boolean compareAndSetRaw(long offset, E expect, E update) { - return unsafe.compareAndSwapObject(array, offset, expect, update); + return U.compareAndSwapObject(array, offset, expect, update); } /** @@ -314,17 +313,20 @@ /** * Reconstitutes the instance from a stream (that is, deserializes it). + * @param s the stream + * @throws ClassNotFoundException if the class of a serialized object + * could not be found + * @throws java.io.IOException if an I/O error occurs */ private void readObject(java.io.ObjectInputStream s) - throws java.io.IOException, ClassNotFoundException, - java.io.InvalidObjectException { + throws java.io.IOException, ClassNotFoundException { // Note: This must be changed if any additional fields are defined Object a = s.readFields().get("array", null); if (a == null || !a.getClass().isArray()) throw new java.io.InvalidObjectException("Not array type"); if (a.getClass() != Object[].class) a = Arrays.copyOf((Object[])a, Array.getLength(a), Object[].class); - unsafe.putObjectVolatile(this, arrayFieldOffset, a); + U.putObjectVolatile(this, ARRAY, a); } } diff -r e331a1a5a621 -r caeef2c79243 jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Tue Sep 29 18:01:33 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Tue Sep 29 16:44:29 2015 +0100 @@ -34,14 +34,14 @@ */ package java.util.concurrent.atomic; -import java.util.function.UnaryOperator; -import java.util.function.BinaryOperator; -import sun.misc.Unsafe; + import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.security.AccessController; +import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; -import java.security.PrivilegedActionException; +import java.util.function.BinaryOperator; +import java.util.function.UnaryOperator; import sun.reflect.CallerSensitive; import sun.reflect.Reflection; @@ -53,7 +53,7 @@ * independently subject to atomic updates. For example, a tree node * might be declared as * - *
 {@code
+ * 
 {@code
  * class Node {
  *   private volatile Node left, right;
  *
@@ -62,7 +62,7 @@
  *   private static AtomicReferenceFieldUpdater rightUpdater =
  *     AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "right");
  *
- *   Node getLeft() { return left;  }
+ *   Node getLeft() { return left; }
  *   boolean compareAndSetLeft(Node expect, Node update) {
  *     return leftUpdater.compareAndSet(this, expect, update);
  *   }
@@ -284,7 +284,7 @@
 
     private static final class AtomicReferenceFieldUpdaterImpl
         extends AtomicReferenceFieldUpdater {
-        private static final Unsafe unsafe = Unsafe.getUnsafe();
+        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
         private final long offset;
         private final Class tclass;
         private final Class vclass;
@@ -323,7 +323,7 @@
                 ClassLoader ccl = caller.getClassLoader();
                 if ((ccl != null) && (ccl != cl) &&
                     ((cl == null) || !isAncestor(cl, ccl))) {
-                  sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
+                    sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
                 }
                 fieldClass = field.getType();
             } catch (PrivilegedActionException pae) {
@@ -347,7 +347,7 @@
                 this.vclass = null;
             else
                 this.vclass = vclass;
-            offset = unsafe.objectFieldOffset(field);
+            offset = U.objectFieldOffset(field);
         }
 
         /**
@@ -386,7 +386,7 @@
                 (update != null && vclass != null &&
                  vclass != update.getClass()))
                 updateCheck(obj, update);
-            return unsafe.compareAndSwapObject(obj, offset, expect, update);
+            return U.compareAndSwapObject(obj, offset, expect, update);
         }
 
         public boolean weakCompareAndSet(T obj, V expect, V update) {
@@ -395,7 +395,7 @@
                 (update != null && vclass != null &&
                  vclass != update.getClass()))
                 updateCheck(obj, update);
-            return unsafe.compareAndSwapObject(obj, offset, expect, update);
+            return U.compareAndSwapObject(obj, offset, expect, update);
         }
 
         public void set(T obj, V newValue) {
@@ -403,7 +403,7 @@
                 (newValue != null && vclass != null &&
                  vclass != newValue.getClass()))
                 updateCheck(obj, newValue);
-            unsafe.putObjectVolatile(obj, offset, newValue);
+            U.putObjectVolatile(obj, offset, newValue);
         }
 
         public void lazySet(T obj, V newValue) {
@@ -411,14 +411,14 @@
                 (newValue != null && vclass != null &&
                  vclass != newValue.getClass()))
                 updateCheck(obj, newValue);
-            unsafe.putOrderedObject(obj, offset, newValue);
+            U.putOrderedObject(obj, offset, newValue);
         }
 
         @SuppressWarnings("unchecked")
         public V get(T obj) {
             if (obj == null || obj.getClass() != tclass || cclass != null)
                 targetCheck(obj);
-            return (V)unsafe.getObjectVolatile(obj, offset);
+            return (V)U.getObjectVolatile(obj, offset);
         }
 
         @SuppressWarnings("unchecked")
@@ -427,7 +427,7 @@
                 (newValue != null && vclass != null &&
                  vclass != newValue.getClass()))
                 updateCheck(obj, newValue);
-            return (V)unsafe.getAndSetObject(obj, offset, newValue);
+            return (V)U.getAndSetObject(obj, offset, newValue);
         }
 
         private void ensureProtectedAccess(T obj) {
diff -r e331a1a5a621 -r caeef2c79243 jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicStampedReference.java
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicStampedReference.java	Tue Sep 29 18:01:33 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicStampedReference.java	Tue Sep 29 16:44:29 2015 +0100
@@ -97,7 +97,7 @@
      * Typical usage is {@code int[1] holder; ref = v.get(holder); }.
      *
      * @param stampHolder an array of size of at least one.  On return,
-     * {@code stampholder[0]} will hold the value of the stamp.
+     * {@code stampHolder[0]} will hold the value of the stamp.
      * @return the current value of the reference
      */
     public V get(int[] stampHolder) {
@@ -190,23 +190,18 @@
 
     // Unsafe mechanics
 
-    private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
-    private static final long pairOffset =
-        objectFieldOffset(UNSAFE, "pair", AtomicStampedReference.class);
-
-    private boolean casPair(Pair cmp, Pair val) {
-        return UNSAFE.compareAndSwapObject(this, pairOffset, cmp, val);
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+    private static final long PAIR;
+    static {
+        try {
+            PAIR = U.objectFieldOffset
+                (AtomicStampedReference.class.getDeclaredField("pair"));
+        } catch (ReflectiveOperationException e) {
+            throw new Error(e);
+        }
     }
 
-    static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
-                                  String field, Class klazz) {
-        try {
-            return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
-        } catch (NoSuchFieldException e) {
-            // Convert Exception to corresponding Error
-            NoSuchFieldError error = new NoSuchFieldError(field);
-            error.initCause(e);
-            throw error;
-        }
+    private boolean casPair(Pair cmp, Pair val) {
+        return U.compareAndSwapObject(this, PAIR, cmp, val);
     }
 }
diff -r e331a1a5a621 -r caeef2c79243 jdk/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java	Tue Sep 29 18:01:33 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java	Tue Sep 29 16:44:29 2015 +0100
@@ -34,6 +34,7 @@
  */
 
 package java.util.concurrent.atomic;
+
 import java.io.Serializable;
 import java.util.function.DoubleBinaryOperator;
 
@@ -126,14 +127,13 @@
      * @return the current value
      */
     public double get() {
-        Cell[] as = cells; Cell a;
+        Cell[] as = cells;
         double result = Double.longBitsToDouble(base);
         if (as != null) {
-            for (int i = 0; i < as.length; ++i) {
-                if ((a = as[i]) != null)
+            for (Cell a : as)
+                if (a != null)
                     result = function.applyAsDouble
                         (result, Double.longBitsToDouble(a.value));
-            }
         }
         return result;
     }
@@ -147,13 +147,12 @@
      * updating.
      */
     public void reset() {
-        Cell[] as = cells; Cell a;
+        Cell[] as = cells;
         base = identity;
         if (as != null) {
-            for (int i = 0; i < as.length; ++i) {
-                if ((a = as[i]) != null)
-                    a.value = identity;
-            }
+            for (Cell a : as)
+                if (a != null)
+                    a.reset(identity);
         }
     }
 
@@ -168,14 +167,14 @@
      * @return the value before reset
      */
     public double getThenReset() {
-        Cell[] as = cells; Cell a;
+        Cell[] as = cells;
         double result = Double.longBitsToDouble(base);
         base = identity;
         if (as != null) {
-            for (int i = 0; i < as.length; ++i) {
-                if ((a = as[i]) != null) {
+            for (Cell a : as) {
+                if (a != null) {
                     double v = Double.longBitsToDouble(a.value);
-                    a.value = identity;
+                    a.reset(identity);
                     result = function.applyAsDouble(result, v);
                 }
             }
@@ -237,21 +236,27 @@
          * @serial
          */
         private final double value;
+
         /**
          * The function used for updates.
          * @serial
          */
         private final DoubleBinaryOperator function;
+
         /**
-         * The identity value
+         * The identity value, represented as a long, as converted by
+         * {@link Double#doubleToRawLongBits}.  The original identity
+         * can be recovered using {@link Double#longBitsToDouble}.
          * @serial
          */
         private final long identity;
 
-        SerializationProxy(DoubleAccumulator a) {
-            function = a.function;
-            identity = a.identity;
-            value = a.get();
+        SerializationProxy(double value,
+                           DoubleBinaryOperator function,
+                           long identity) {
+            this.value = value;
+            this.function = function;
+            this.identity = identity;
         }
 
         /**
@@ -259,7 +264,7 @@
          * held by this proxy.
          *
          * @return a {@code DoubleAccumulator} object with initial state
-         * held by this proxy.
+         * held by this proxy
          */
         private Object readResolve() {
             double d = Double.longBitsToDouble(identity);
@@ -279,7 +284,7 @@
      * representing the state of this instance
      */
     private Object writeReplace() {
-        return new SerializationProxy(this);
+        return new SerializationProxy(get(), function, identity);
     }
 
     /**
diff -r e331a1a5a621 -r caeef2c79243 jdk/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAdder.java
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAdder.java	Tue Sep 29 18:01:33 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAdder.java	Tue Sep 29 16:44:29 2015 +0100
@@ -34,6 +34,7 @@
  */
 
 package java.util.concurrent.atomic;
+
 import java.io.Serializable;
 
 /**
@@ -114,13 +115,12 @@
      * @return the sum
      */
     public double sum() {
-        Cell[] as = cells; Cell a;
+        Cell[] as = cells;
         double sum = Double.longBitsToDouble(base);
         if (as != null) {
-            for (int i = 0; i < as.length; ++i) {
-                if ((a = as[i]) != null)
+            for (Cell a : as)
+                if (a != null)
                     sum += Double.longBitsToDouble(a.value);
-            }
         }
         return sum;
     }
@@ -133,13 +133,12 @@
      * known that no threads are concurrently updating.
      */
     public void reset() {
-        Cell[] as = cells; Cell a;
+        Cell[] as = cells;
         base = 0L; // relies on fact that double 0 must have same rep as long
         if (as != null) {
-            for (int i = 0; i < as.length; ++i) {
-                if ((a = as[i]) != null)
-                    a.value = 0L;
-            }
+            for (Cell a : as)
+                if (a != null)
+                    a.reset();
         }
     }
 
@@ -154,14 +153,14 @@
      * @return the sum
      */
     public double sumThenReset() {
-        Cell[] as = cells; Cell a;
+        Cell[] as = cells;
         double sum = Double.longBitsToDouble(base);
         base = 0L;
         if (as != null) {
-            for (int i = 0; i < as.length; ++i) {
-                if ((a = as[i]) != null) {
+            for (Cell a : as) {
+                if (a != null) {
                     long v = a.value;
-                    a.value = 0L;
+                    a.reset();
                     sum += Double.longBitsToDouble(v);
                 }
             }
@@ -233,7 +232,7 @@
          * held by this proxy.
          *
          * @return a {@code DoubleAdder} object with initial state
-         * held by this proxy.
+         * held by this proxy
          */
         private Object readResolve() {
             DoubleAdder a = new DoubleAdder();
diff -r e331a1a5a621 -r caeef2c79243 jdk/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java	Tue Sep 29 18:01:33 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java	Tue Sep 29 16:44:29 2015 +0100
@@ -34,6 +34,7 @@
  */
 
 package java.util.concurrent.atomic;
+
 import java.io.Serializable;
 import java.util.function.LongBinaryOperator;
 
@@ -124,13 +125,12 @@
      * @return the current value
      */
     public long get() {
-        Cell[] as = cells; Cell a;
+        Cell[] as = cells;
         long result = base;
         if (as != null) {
-            for (int i = 0; i < as.length; ++i) {
-                if ((a = as[i]) != null)
+            for (Cell a : as)
+                if (a != null)
                     result = function.applyAsLong(result, a.value);
-            }
         }
         return result;
     }
@@ -144,13 +144,12 @@
      * updating.
      */
     public void reset() {
-        Cell[] as = cells; Cell a;
+        Cell[] as = cells;
         base = identity;
         if (as != null) {
-            for (int i = 0; i < as.length; ++i) {
-                if ((a = as[i]) != null)
-                    a.value = identity;
-            }
+            for (Cell a : as)
+                if (a != null)
+                    a.reset(identity);
         }
     }
 
@@ -165,14 +164,14 @@
      * @return the value before reset
      */
     public long getThenReset() {
-        Cell[] as = cells; Cell a;
+        Cell[] as = cells;
         long result = base;
         base = identity;
         if (as != null) {
-            for (int i = 0; i < as.length; ++i) {
-                if ((a = as[i]) != null) {
+            for (Cell a : as) {
+                if (a != null) {
                     long v = a.value;
-                    a.value = identity;
+                    a.reset(identity);
                     result = function.applyAsLong(result, v);
                 }
             }
@@ -234,21 +233,25 @@
          * @serial
          */
         private final long value;
+
         /**
          * The function used for updates.
          * @serial
          */
         private final LongBinaryOperator function;
+
         /**
-         * The identity value
+         * The identity value.
          * @serial
          */
         private final long identity;
 
-        SerializationProxy(LongAccumulator a) {
-            function = a.function;
-            identity = a.identity;
-            value = a.get();
+        SerializationProxy(long value,
+                           LongBinaryOperator function,
+                           long identity) {
+            this.value = value;
+            this.function = function;
+            this.identity = identity;
         }
 
         /**
@@ -256,7 +259,7 @@
          * held by this proxy.
          *
          * @return a {@code LongAccumulator} object with initial state
-         * held by this proxy.
+         * held by this proxy
          */
         private Object readResolve() {
             LongAccumulator a = new LongAccumulator(function, identity);
@@ -275,7 +278,7 @@
      * representing the state of this instance
      */
     private Object writeReplace() {
-        return new SerializationProxy(this);
+        return new SerializationProxy(get(), function, identity);
     }
 
     /**
diff -r e331a1a5a621 -r caeef2c79243 jdk/src/java.base/share/classes/java/util/concurrent/atomic/LongAdder.java
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/LongAdder.java	Tue Sep 29 18:01:33 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/LongAdder.java	Tue Sep 29 16:44:29 2015 +0100
@@ -34,6 +34,7 @@
  */
 
 package java.util.concurrent.atomic;
+
 import java.io.Serializable;
 
 /**
@@ -116,13 +117,12 @@
      * @return the sum
      */
     public long sum() {
-        Cell[] as = cells; Cell a;
+        Cell[] as = cells;
         long sum = base;
         if (as != null) {
-            for (int i = 0; i < as.length; ++i) {
-                if ((a = as[i]) != null)
+            for (Cell a : as)
+                if (a != null)
                     sum += a.value;
-            }
         }
         return sum;
     }
@@ -135,13 +135,12 @@
      * known that no threads are concurrently updating.
      */
     public void reset() {
-        Cell[] as = cells; Cell a;
+        Cell[] as = cells;
         base = 0L;
         if (as != null) {
-            for (int i = 0; i < as.length; ++i) {
-                if ((a = as[i]) != null)
-                    a.value = 0L;
-            }
+            for (Cell a : as)
+                if (a != null)
+                    a.reset();
         }
     }
 
@@ -156,14 +155,14 @@
      * @return the sum
      */
     public long sumThenReset() {
-        Cell[] as = cells; Cell a;
+        Cell[] as = cells;
         long sum = base;
         base = 0L;
         if (as != null) {
-            for (int i = 0; i < as.length; ++i) {
-                if ((a = as[i]) != null) {
+            for (Cell a : as) {
+                if (a != null) {
                     sum += a.value;
-                    a.value = 0L;
+                    a.reset();
                 }
             }
         }
@@ -230,11 +229,11 @@
         }
 
         /**
-         * Return a {@code LongAdder} object with initial state
+         * Returns a {@code LongAdder} object with initial state
          * held by this proxy.
          *
          * @return a {@code LongAdder} object with initial state
-         * held by this proxy.
+         * held by this proxy
          */
         private Object readResolve() {
             LongAdder a = new LongAdder();
diff -r e331a1a5a621 -r caeef2c79243 jdk/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java	Tue Sep 29 18:01:33 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java	Tue Sep 29 16:44:29 2015 +0100
@@ -34,9 +34,11 @@
  */
 
 package java.util.concurrent.atomic;
-import java.util.function.LongBinaryOperator;
+
+import java.util.Arrays;
+import java.util.concurrent.ThreadLocalRandom;
 import java.util.function.DoubleBinaryOperator;
-import java.util.concurrent.ThreadLocalRandom;
+import java.util.function.LongBinaryOperator;
 
 /**
  * A package-local class holding common representation and mechanics
@@ -121,19 +123,23 @@
         volatile long value;
         Cell(long x) { value = x; }
         final boolean cas(long cmp, long val) {
-            return UNSAFE.compareAndSwapLong(this, valueOffset, cmp, val);
+            return U.compareAndSwapLong(this, VALUE, cmp, val);
+        }
+        final void reset() {
+            U.putLongVolatile(this, VALUE, 0L);
+        }
+        final void reset(long identity) {
+            U.putLongVolatile(this, VALUE, identity);
         }
 
         // Unsafe mechanics
-        private static final sun.misc.Unsafe UNSAFE;
-        private static final long valueOffset;
+        private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+        private static final long VALUE;
         static {
             try {
-                UNSAFE = sun.misc.Unsafe.getUnsafe();
-                Class ak = Cell.class;
-                valueOffset = UNSAFE.objectFieldOffset
-                    (ak.getDeclaredField("value"));
-            } catch (Exception e) {
+                VALUE = U.objectFieldOffset
+                    (Cell.class.getDeclaredField("value"));
+            } catch (ReflectiveOperationException e) {
                 throw new Error(e);
             }
         }
@@ -159,7 +165,7 @@
     transient volatile int cellsBusy;
 
     /**
-     * Package-private default constructor
+     * Package-private default constructor.
      */
     Striped64() {
     }
@@ -168,14 +174,14 @@
      * CASes the base field.
      */
     final boolean casBase(long cmp, long val) {
-        return UNSAFE.compareAndSwapLong(this, BASE, cmp, val);
+        return U.compareAndSwapLong(this, BASE, cmp, val);
     }
 
     /**
      * CASes the cellsBusy field from 0 to 1 to acquire lock.
      */
     final boolean casCellsBusy() {
-        return UNSAFE.compareAndSwapInt(this, CELLSBUSY, 0, 1);
+        return U.compareAndSwapInt(this, CELLSBUSY, 0, 1);
     }
 
     /**
@@ -183,7 +189,7 @@
      * Duplicated from ThreadLocalRandom because of packaging restrictions.
      */
     static final int getProbe() {
-        return UNSAFE.getInt(Thread.currentThread(), PROBE);
+        return U.getInt(Thread.currentThread(), PROBE);
     }
 
     /**
@@ -195,7 +201,7 @@
         probe ^= probe << 13;   // xorshift
         probe ^= probe >>> 17;
         probe ^= probe << 5;
-        UNSAFE.putInt(Thread.currentThread(), PROBE, probe);
+        U.putInt(Thread.currentThread(), PROBE, probe);
         return probe;
     }
 
@@ -220,27 +226,24 @@
             wasUncontended = true;
         }
         boolean collide = false;                // True if last slot nonempty
-        for (;;) {
+        done: for (;;) {
             Cell[] as; Cell a; int n; long v;
             if ((as = cells) != null && (n = as.length) > 0) {
                 if ((a = as[(n - 1) & h]) == null) {
                     if (cellsBusy == 0) {       // Try to attach new Cell
                         Cell r = new Cell(x);   // Optimistically create
                         if (cellsBusy == 0 && casCellsBusy()) {
-                            boolean created = false;
                             try {               // Recheck under lock
                                 Cell[] rs; int m, j;
                                 if ((rs = cells) != null &&
                                     (m = rs.length) > 0 &&
                                     rs[j = (m - 1) & h] == null) {
                                     rs[j] = r;
-                                    created = true;
+                                    break done;
                                 }
                             } finally {
                                 cellsBusy = 0;
                             }
-                            if (created)
-                                break;
                             continue;           // Slot is now non-empty
                         }
                     }
@@ -248,8 +251,8 @@
                 }
                 else if (!wasUncontended)       // CAS already known to fail
                     wasUncontended = true;      // Continue after rehash
-                else if (a.cas(v = a.value, ((fn == null) ? v + x :
-                                             fn.applyAsLong(v, x))))
+                else if (a.cas(v = a.value,
+                               (fn == null) ? v + x : fn.applyAsLong(v, x)))
                     break;
                 else if (n >= NCPU || cells != as)
                     collide = false;            // At max size or stale
@@ -257,12 +260,8 @@
                     collide = true;
                 else if (cellsBusy == 0 && casCellsBusy()) {
                     try {
-                        if (cells == as) {      // Expand table unless stale
-                            Cell[] rs = new Cell[n << 1];
-                            for (int i = 0; i < n; ++i)
-                                rs[i] = as[i];
-                            cells = rs;
-                        }
+                        if (cells == as)        // Expand table unless stale
+                            cells = Arrays.copyOf(as, n << 1);
                     } finally {
                         cellsBusy = 0;
                     }
@@ -272,26 +271,30 @@
                 h = advanceProbe(h);
             }
             else if (cellsBusy == 0 && cells == as && casCellsBusy()) {
-                boolean init = false;
                 try {                           // Initialize table
                     if (cells == as) {
                         Cell[] rs = new Cell[2];
                         rs[h & 1] = new Cell(x);
                         cells = rs;
-                        init = true;
+                        break done;
                     }
                 } finally {
                     cellsBusy = 0;
                 }
-                if (init)
-                    break;
             }
-            else if (casBase(v = base, ((fn == null) ? v + x :
-                                        fn.applyAsLong(v, x))))
-                break;                          // Fall back on using base
+            // Fall back on using base
+            else if (casBase(v = base,
+                             (fn == null) ? v + x : fn.applyAsLong(v, x)))
+                break done;
         }
     }
 
+    private static long apply(DoubleBinaryOperator fn, long v, double x) {
+        double d = Double.longBitsToDouble(v);
+        d = (fn == null) ? d + x : fn.applyAsDouble(d, x);
+        return Double.doubleToRawLongBits(d);
+    }
+
     /**
      * Same as longAccumulate, but injecting long/double conversions
      * in too many places to sensibly merge with long version, given
@@ -307,27 +310,24 @@
             wasUncontended = true;
         }
         boolean collide = false;                // True if last slot nonempty
-        for (;;) {
+        done: for (;;) {
             Cell[] as; Cell a; int n; long v;
             if ((as = cells) != null && (n = as.length) > 0) {
                 if ((a = as[(n - 1) & h]) == null) {
                     if (cellsBusy == 0) {       // Try to attach new Cell
                         Cell r = new Cell(Double.doubleToRawLongBits(x));
                         if (cellsBusy == 0 && casCellsBusy()) {
-                            boolean created = false;
                             try {               // Recheck under lock
                                 Cell[] rs; int m, j;
                                 if ((rs = cells) != null &&
                                     (m = rs.length) > 0 &&
                                     rs[j = (m - 1) & h] == null) {
                                     rs[j] = r;
-                                    created = true;
+                                    break done;
                                 }
                             } finally {
                                 cellsBusy = 0;
                             }
-                            if (created)
-                                break;
                             continue;           // Slot is now non-empty
                         }
                     }
@@ -335,13 +335,7 @@
                 }
                 else if (!wasUncontended)       // CAS already known to fail
                     wasUncontended = true;      // Continue after rehash
-                else if (a.cas(v = a.value,
-                               ((fn == null) ?
-                                Double.doubleToRawLongBits
-                                (Double.longBitsToDouble(v) + x) :
-                                Double.doubleToRawLongBits
-                                (fn.applyAsDouble
-                                 (Double.longBitsToDouble(v), x)))))
+                else if (a.cas(v = a.value, apply(fn, v, x)))
                     break;
                 else if (n >= NCPU || cells != as)
                     collide = false;            // At max size or stale
@@ -349,12 +343,8 @@
                     collide = true;
                 else if (cellsBusy == 0 && casCellsBusy()) {
                     try {
-                        if (cells == as) {      // Expand table unless stale
-                            Cell[] rs = new Cell[n << 1];
-                            for (int i = 0; i < n; ++i)
-                                rs[i] = as[i];
-                            cells = rs;
-                        }
+                        if (cells == as)        // Expand table unless stale
+                            cells = Arrays.copyOf(as, n << 1);
                     } finally {
                         cellsBusy = 0;
                     }
@@ -364,48 +354,38 @@
                 h = advanceProbe(h);
             }
             else if (cellsBusy == 0 && cells == as && casCellsBusy()) {
-                boolean init = false;
                 try {                           // Initialize table
                     if (cells == as) {
                         Cell[] rs = new Cell[2];
                         rs[h & 1] = new Cell(Double.doubleToRawLongBits(x));
                         cells = rs;
-                        init = true;
+                        break done;
                     }
                 } finally {
                     cellsBusy = 0;
                 }
-                if (init)
-                    break;
             }
-            else if (casBase(v = base,
-                             ((fn == null) ?
-                              Double.doubleToRawLongBits
-                              (Double.longBitsToDouble(v) + x) :
-                              Double.doubleToRawLongBits
-                              (fn.applyAsDouble
-                               (Double.longBitsToDouble(v), x)))))
-                break;                          // Fall back on using base
+            // Fall back on using base
+            else if (casBase(v = base, apply(fn, v, x)))
+                break done;
         }
     }
 
     // Unsafe mechanics
-    private static final sun.misc.Unsafe UNSAFE;
+    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
     private static final long BASE;
     private static final long CELLSBUSY;
     private static final long PROBE;
     static {
         try {
-            UNSAFE = sun.misc.Unsafe.getUnsafe();
-            Class sk = Striped64.class;
-            BASE = UNSAFE.objectFieldOffset
-                (sk.getDeclaredField("base"));
-            CELLSBUSY = UNSAFE.objectFieldOffset
-                (sk.getDeclaredField("cellsBusy"));
-            Class tk = Thread.class;
-            PROBE = UNSAFE.objectFieldOffset
-                (tk.getDeclaredField("threadLocalRandomProbe"));
-        } catch (Exception e) {
+            BASE = U.objectFieldOffset
+                (Striped64.class.getDeclaredField("base"));
+            CELLSBUSY = U.objectFieldOffset
+                (Striped64.class.getDeclaredField("cellsBusy"));
+
+            PROBE = U.objectFieldOffset
+                (Thread.class.getDeclaredField("threadLocalRandomProbe"));
+        } catch (ReflectiveOperationException e) {
             throw new Error(e);
         }
     }
diff -r e331a1a5a621 -r caeef2c79243 jdk/src/java.base/share/classes/java/util/concurrent/atomic/package-info.java
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/package-info.java	Tue Sep 29 18:01:33 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/package-info.java	Tue Sep 29 16:44:29 2015 +0100
@@ -40,7 +40,7 @@
  * array elements to those that also provide an atomic conditional update
  * operation of the form:
  *
- *  
 {@code boolean compareAndSet(expectedValue, updateValue);}
+ *
 {@code boolean compareAndSet(expectedValue, updateValue);}
* *

This method (which varies in argument types across different * classes) atomically sets a variable to the {@code updateValue} if it @@ -67,7 +67,7 @@ * {@code AtomicInteger} provide atomic increment methods. One * application is to generate sequence numbers, as in: * - *

 {@code
+ * 
 {@code
  * class Sequencer {
  *   private final AtomicLong sequenceNumber
  *     = new AtomicLong(0);
@@ -82,7 +82,7 @@
  * 
 {@code long transform(long input)}
* * write your utility method as follows: - *
 {@code
+ * 
 {@code
  * long getAndTransform(AtomicLong var) {
  *   long prev, next;
  *   do {
@@ -94,18 +94,19 @@
  *
  * 

The memory effects for accesses and updates of atomics generally * follow the rules for volatiles, as stated in - * - * The Java Language Specification (17.4 Memory Model): + * + * Chapter 17 of + * The Java™ Language Specification: * *

    * - *
  • {@code get} has the memory effects of reading a + *
  • {@code get} has the memory effects of reading a * {@code volatile} variable. * - *
  • {@code set} has the memory effects of writing (assigning) a + *
  • {@code set} has the memory effects of writing (assigning) a * {@code volatile} variable. * - *
  • {@code lazySet} has the memory effects of writing (assigning) + *
  • {@code lazySet} has the memory effects of writing (assigning) * a {@code volatile} variable except that it permits reorderings with * subsequent (but not previous) memory actions that do not themselves * impose reordering constraints with ordinary non-{@code volatile} @@ -119,7 +120,7 @@ * with respect to previous or subsequent reads and writes of any * variables other than the target of the {@code weakCompareAndSet}. * - *
  • {@code compareAndSet} + *
  • {@code compareAndSet} * and all other read-and-update operations such as {@code getAndIncrement} * have the memory effects of both reading and * writing {@code volatile} variables.