--- jsr166/src/jsr166e/extra/AtomicDoubleArray.java 2011/08/10 02:03:29 1.1 +++ jsr166/src/jsr166e/extra/AtomicDoubleArray.java 2013/03/04 16:09:25 1.9 @@ -14,13 +14,13 @@ import static java.lang.Double.longBitsT * See the {@link java.util.concurrent.atomic} package specification * for description of the properties of atomic variables. * - *
This class compares primitive {@code double}
+ * This class compares primitive {@code double}
* values in methods such as {@link #compareAndSet} by comparing their
* bitwise representation using {@link Double#doubleToRawLongBits},
* which differs from both the primitive double {@code ==} operator
* and from {@link Double#equals}, as if implemented by:
* May fail spuriously
- * and does not provide ordering guarantees, so is only rarely an
- * appropriate alternative to {@code compareAndSet}.
+ *
+
+ * May fail spuriously and does not provide ordering guarantees,
+ * so is only rarely an appropriate alternative to {@code compareAndSet}.
*
* @param i the index
* @param expect the expected value
@@ -222,9 +224,10 @@ public class AtomicDoubleArray implement
if (iMax == -1)
return "[]";
- StringBuilder b = new StringBuilder();
+ // Double.toString(Math.PI).length() == 17
+ StringBuilder b = new StringBuilder((17 + 2) * (iMax + 1));
b.append('[');
- for (int i = 0; ; i++) {
+ for (int i = 0;; i++) {
b.append(longBitsToDouble(getRaw(byteOffset(i))));
if (i == iMax)
return b.append(']').toString();
@@ -232,16 +235,59 @@ public class AtomicDoubleArray implement
}
}
+ /**
+ * Saves the state to a stream (that is, serializes it).
+ *
+ * @serialData The length of the array is emitted (int), followed by all
+ * of its elements (each a {@code double}) in the proper order.
+ */
+ private void writeObject(java.io.ObjectOutputStream s)
+ throws java.io.IOException {
+ s.defaultWriteObject();
+
+ // Write out array length
+ int length = length();
+ s.writeInt(length);
+
+ // Write out all elements in the proper order.
+ for (int i = 0; i < length; i++)
+ s.writeDouble(get(i));
+ }
+
+ /**
+ * Reconstitutes the instance from a stream (that is, deserializes it).
+ */
+ private void readObject(java.io.ObjectInputStream s)
+ throws java.io.IOException, ClassNotFoundException {
+ s.defaultReadObject();
+
+ // Read in array length and allocate array
+ int length = s.readInt();
+ unsafe.putObjectVolatile(this, arrayOffset, new long[length]);
+
+ // Read in all elements in the proper order.
+ for (int i = 0; i < length; i++)
+ set(i, s.readDouble());
+ }
+
// Unsafe mechanics
private static final sun.misc.Unsafe unsafe = getUnsafe();
+ private static final long arrayOffset;
private static final int base = unsafe.arrayBaseOffset(long[].class);
private static final int shift;
static {
- int scale = unsafe.arrayIndexScale(long[].class);
- if ((scale & (scale - 1)) != 0)
- throw new Error("data type scale not a power of two");
- shift = 31 - Integer.numberOfLeadingZeros(scale);
+ try {
+ Class> k = AtomicDoubleArray.class;
+ arrayOffset = unsafe.objectFieldOffset
+ (k.getDeclaredField("array"));
+ int scale = unsafe.arrayIndexScale(long[].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(e);
+ }
}
/**
@@ -254,21 +300,23 @@ public class AtomicDoubleArray implement
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 {@code
- * boolean bitEquals(double x, double y) {
+ * static boolean bitEquals(double x, double y) {
* long xBits = Double.doubleToRawLongBits(x);
* long yBits = Double.doubleToRawLongBits(y);
* return xBits == yBits;
@@ -32,7 +32,7 @@ import static java.lang.Double.longBitsT
public class AtomicDoubleArray implements java.io.Serializable {
private static final long serialVersionUID = -2308431214976778248L;
- private final long[] array;
+ private final transient long[] array;
private long checkedByteOffset(int i) {
if (i < 0 || i >= array.length)
@@ -162,9 +162,11 @@ public class AtomicDoubleArray implement
* if the current value is bitwise equal
* to the expected value.
*
- *