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

Comparing jsr166/src/jsr166e/extra/AtomicDouble.java (file contents):
Revision 1.2 by jsr166, Tue Aug 9 07:44:08 2011 UTC vs.
Revision 1.4 by jsr166, Tue Aug 9 19:10:29 2011 UTC

# Line 8 | Line 8
8   package jsr166e.extra;
9   import static java.lang.Double.doubleToRawLongBits;
10   import static java.lang.Double.longBitsToDouble;
11 import sun.misc.Unsafe;
11  
12   /**
13   * A {@code double} value that may be updated atomically.  See the
14   * {@link java.util.concurrent.atomic} package specification for
15   * description of the properties of atomic variables.  An {@code
16 < * AtomicDouble} is used in applications such as atomic summation, and
17 < * cannot be used as a replacement for a {@link Double}.  However,
16 > * AtomicDouble} is used in applications such as atomic accumulation,
17 > * and cannot be used as a replacement for a {@link Double}.  However,
18   * this class does extend {@code Number} to allow uniform access by
19   * tools and utilities that deal with numerically-based classes.
20   *
# Line 29 | Line 28 | import sun.misc.Unsafe;
28   *   long yBits = Double.doubleToRawLongBits(y);
29   *   return xBits == yBits;
30   * }}</pre>
31 < *
33 < * @since 1.5
31 > *
32   * @author Doug Lea
33   * @author Martin Buchholz
34   */
35   public class AtomicDouble extends Number implements java.io.Serializable {
36 <    private static final long serialVersionUID = 1927816293512124184L;
36 >    static final long serialVersionUID = -8405198993435143622L;
37  
38      // setup to use Unsafe.compareAndSwapLong for updates
39 <    private static final Unsafe unsafe = Unsafe.getUnsafe();
39 >    private static final sun.misc.Unsafe unsafe = getUnsafe();
40      private static final long valueOffset;
41  
44    /**
45     * Records whether the underlying JVM supports lockless
46     * compareAndSwap for longs. While the Unsafe.compareAndSwapLong
47     * method works in either case, some constructions should be
48     * handled at Java level to avoid locking user-visible locks.
49     */
50    static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8();
51
52    /**
53     * Returns whether underlying JVM supports lockless CompareAndSet
54     * for longs. Called only once and cached in VM_SUPPORTS_LONG_CAS.
55     */
56    private static boolean VMSupportsCS8() {
57        try {
58            Class<?> klazz = java.util.concurrent.atomic.AtomicLong.class;
59            java.lang.reflect.Method m =
60                klazz.getDeclaredMethod("VMSupportsCS8", new Class<?>[0]);
61            m.setAccessible(true);
62            return (Boolean) m.invoke(new Class<?>[0]);
63        } catch (Throwable t) { throw new Error(t); }
64    }
65
42      static {
43          try {
44              valueOffset = unsafe.objectFieldOffset
# Line 108 | Line 84 | public class AtomicDouble extends Number
84       * Eventually sets to the given value.
85       *
86       * @param newValue the new value
111     * @since 1.6
87       */
88      public final void lazySet(double newValue) {
89          unsafe.putOrderedLong(this, valueOffset, doubleToRawLongBits(newValue));
# Line 232 | Line 207 | public class AtomicDouble extends Number
207          return get();
208      }
209  
210 +    /**
211 +     * Returns a sun.misc.Unsafe.  Suitable for use in a 3rd party package.
212 +     * Replace with a simple call to Unsafe.getUnsafe when integrating
213 +     * into a jdk.
214 +     *
215 +     * @return a sun.misc.Unsafe
216 +     */
217 +    private static sun.misc.Unsafe getUnsafe() {
218 +        try {
219 +            return sun.misc.Unsafe.getUnsafe();
220 +        } catch (SecurityException se) {
221 +            try {
222 +                return java.security.AccessController.doPrivileged
223 +                    (new java.security
224 +                     .PrivilegedExceptionAction<sun.misc.Unsafe>() {
225 +                        public sun.misc.Unsafe run() throws Exception {
226 +                            java.lang.reflect.Field f = sun.misc
227 +                                .Unsafe.class.getDeclaredField("theUnsafe");
228 +                            f.setAccessible(true);
229 +                            return (sun.misc.Unsafe) f.get(null);
230 +                        }});
231 +            } catch (java.security.PrivilegedActionException e) {
232 +                throw new RuntimeException("Could not initialize intrinsics",
233 +                                           e.getCause());
234 +            }
235 +        }
236 +    }
237 +
238   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines