ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/extra/AtomicDoubleArray.java
(Generate patch)

Comparing jsr166/src/jsr166e/extra/AtomicDoubleArray.java (file contents):
Revision 1.1 by jsr166, Wed Aug 10 02:03:29 2011 UTC vs.
Revision 1.9 by jsr166, Mon Mar 4 16:09:25 2013 UTC

# Line 14 | Line 14 | import static java.lang.Double.longBitsT
14   * See the {@link java.util.concurrent.atomic} package specification
15   * for description of the properties of atomic variables.
16   *
17 < * <p><a name="bitEquals">This class compares primitive {@code double}
17 > * <p id="bitEquals">This class compares primitive {@code double}
18   * values in methods such as {@link #compareAndSet} by comparing their
19   * bitwise representation using {@link Double#doubleToRawLongBits},
20   * which differs from both the primitive double {@code ==} operator
21   * and from {@link Double#equals}, as if implemented by:
22   *  <pre> {@code
23 < * boolean bitEquals(double x, double y) {
23 > * static boolean bitEquals(double x, double y) {
24   *   long xBits = Double.doubleToRawLongBits(x);
25   *   long yBits = Double.doubleToRawLongBits(y);
26   *   return xBits == yBits;
# Line 32 | Line 32 | import static java.lang.Double.longBitsT
32   public class AtomicDoubleArray implements java.io.Serializable {
33      private static final long serialVersionUID = -2308431214976778248L;
34  
35 <    private final long[] array;
35 >    private final transient long[] array;
36  
37      private long checkedByteOffset(int i) {
38          if (i < 0 || i >= array.length)
# Line 162 | Line 162 | public class AtomicDoubleArray implement
162       * if the current value is <a href="#bitEquals">bitwise equal</a>
163       * to the expected value.
164       *
165 <     * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
166 <     * and does not provide ordering guarantees, so is only rarely an
167 <     * appropriate alternative to {@code compareAndSet}.
165 >     * <p><a
166 >     * href="http://download.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/package-summary.html#Spurious">
167 >
168 >     * May fail spuriously and does not provide ordering guarantees</a>,
169 >     * so is only rarely an appropriate alternative to {@code compareAndSet}.
170       *
171       * @param i the index
172       * @param expect the expected value
# Line 222 | Line 224 | public class AtomicDoubleArray implement
224          if (iMax == -1)
225              return "[]";
226  
227 <        StringBuilder b = new StringBuilder();
227 >        // Double.toString(Math.PI).length() == 17
228 >        StringBuilder b = new StringBuilder((17 + 2) * (iMax + 1));
229          b.append('[');
230 <        for (int i = 0; ; i++) {
230 >        for (int i = 0;; i++) {
231              b.append(longBitsToDouble(getRaw(byteOffset(i))));
232              if (i == iMax)
233                  return b.append(']').toString();
# Line 232 | Line 235 | public class AtomicDoubleArray implement
235          }
236      }
237  
238 +    /**
239 +     * Saves the state to a stream (that is, serializes it).
240 +     *
241 +     * @serialData The length of the array is emitted (int), followed by all
242 +     *             of its elements (each a {@code double}) in the proper order.
243 +     */
244 +    private void writeObject(java.io.ObjectOutputStream s)
245 +        throws java.io.IOException {
246 +        s.defaultWriteObject();
247 +
248 +        // Write out array length
249 +        int length = length();
250 +        s.writeInt(length);
251 +
252 +        // Write out all elements in the proper order.
253 +        for (int i = 0; i < length; i++)
254 +            s.writeDouble(get(i));
255 +    }
256 +
257 +    /**
258 +     * Reconstitutes the instance from a stream (that is, deserializes it).
259 +     */
260 +    private void readObject(java.io.ObjectInputStream s)
261 +        throws java.io.IOException, ClassNotFoundException {
262 +        s.defaultReadObject();
263 +
264 +        // Read in array length and allocate array
265 +        int length = s.readInt();
266 +        unsafe.putObjectVolatile(this, arrayOffset, new long[length]);
267 +
268 +        // Read in all elements in the proper order.
269 +        for (int i = 0; i < length; i++)
270 +            set(i, s.readDouble());
271 +    }
272 +
273      // Unsafe mechanics
274      private static final sun.misc.Unsafe unsafe = getUnsafe();
275 +    private static final long arrayOffset;
276      private static final int base = unsafe.arrayBaseOffset(long[].class);
277      private static final int shift;
278  
279      static {
280 <        int scale = unsafe.arrayIndexScale(long[].class);
281 <        if ((scale & (scale - 1)) != 0)
282 <            throw new Error("data type scale not a power of two");
283 <        shift = 31 - Integer.numberOfLeadingZeros(scale);
280 >        try {
281 >            Class<?> k = AtomicDoubleArray.class;
282 >            arrayOffset = unsafe.objectFieldOffset
283 >                (k.getDeclaredField("array"));
284 >            int scale = unsafe.arrayIndexScale(long[].class);
285 >            if ((scale & (scale - 1)) != 0)
286 >                throw new Error("data type scale not a power of two");
287 >            shift = 31 - Integer.numberOfLeadingZeros(scale);
288 >        } catch (Exception e) {
289 >            throw new Error(e);
290 >        }
291      }
292  
293      /**
# Line 254 | Line 300 | public class AtomicDoubleArray implement
300      private static sun.misc.Unsafe getUnsafe() {
301          try {
302              return sun.misc.Unsafe.getUnsafe();
303 <        } catch (SecurityException se) {
304 <            try {
305 <                return java.security.AccessController.doPrivileged
306 <                    (new java.security
307 <                     .PrivilegedExceptionAction<sun.misc.Unsafe>() {
308 <                        public sun.misc.Unsafe run() throws Exception {
309 <                            java.lang.reflect.Field f = sun.misc
310 <                                .Unsafe.class.getDeclaredField("theUnsafe");
311 <                            f.setAccessible(true);
312 <                            return (sun.misc.Unsafe) f.get(null);
313 <                        }});
314 <            } catch (java.security.PrivilegedActionException e) {
315 <                throw new RuntimeException("Could not initialize intrinsics",
316 <                                           e.getCause());
317 <            }
303 >        } catch (SecurityException tryReflectionInstead) {}
304 >        try {
305 >            return java.security.AccessController.doPrivileged
306 >            (new java.security.PrivilegedExceptionAction<sun.misc.Unsafe>() {
307 >                public sun.misc.Unsafe run() throws Exception {
308 >                    Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class;
309 >                    for (java.lang.reflect.Field f : k.getDeclaredFields()) {
310 >                        f.setAccessible(true);
311 >                        Object x = f.get(null);
312 >                        if (k.isInstance(x))
313 >                            return k.cast(x);
314 >                    }
315 >                    throw new NoSuchFieldError("the Unsafe");
316 >                }});
317 >        } catch (java.security.PrivilegedActionException e) {
318 >            throw new RuntimeException("Could not initialize intrinsics",
319 >                                       e.getCause());
320          }
321      }
322   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines