ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/extra/AtomicDouble.java
Revision: 1.19
Committed: Mon Jul 22 16:47:46 2013 UTC (10 years, 10 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.18: +6 -0 lines
Log Message:
fix javadoc warnings for serialization methods

File Contents

# User Rev Content
1 jsr166 1.1 /*
2 jsr166 1.2 * Written by Doug Lea and Martin Buchholz with assistance from
3     * members of JCP JSR-166 Expert Group and released to the public
4     * domain, as explained at
5 jsr166 1.1 * http://creativecommons.org/publicdomain/zero/1.0/
6     */
7    
8     package jsr166e.extra;
9 jsr166 1.5
10 jsr166 1.1 import static java.lang.Double.doubleToRawLongBits;
11     import static java.lang.Double.longBitsToDouble;
12    
13     /**
14     * A {@code double} value that may be updated atomically. See the
15     * {@link java.util.concurrent.atomic} package specification for
16 jsr166 1.2 * description of the properties of atomic variables. An {@code
17 jsr166 1.3 * AtomicDouble} is used in applications such as atomic accumulation,
18     * and cannot be used as a replacement for a {@link Double}. However,
19 jsr166 1.2 * this class does extend {@code Number} to allow uniform access by
20     * tools and utilities that deal with numerically-based classes.
21 jsr166 1.1 *
22 jsr166 1.16 * <p id="bitEquals">This class compares primitive {@code double}
23 jsr166 1.5 * values in methods such as {@link #compareAndSet} by comparing their
24     * bitwise representation using {@link Double#doubleToRawLongBits},
25     * which differs from both the primitive double {@code ==} operator
26     * and from {@link Double#equals}, as if implemented by:
27 jsr166 1.2 * <pre> {@code
28 jsr166 1.10 * static boolean bitEquals(double x, double y) {
29 jsr166 1.2 * long xBits = Double.doubleToRawLongBits(x);
30     * long yBits = Double.doubleToRawLongBits(y);
31     * return xBits == yBits;
32 jsr166 1.16 * }}</pre>
33 jsr166 1.3 *
34 jsr166 1.7 * @see jsr166e.DoubleAdder
35     * @see jsr166e.DoubleMaxUpdater
36     *
37 jsr166 1.1 * @author Doug Lea
38 jsr166 1.2 * @author Martin Buchholz
39 jsr166 1.1 */
40     public class AtomicDouble extends Number implements java.io.Serializable {
41 jsr166 1.8 private static final long serialVersionUID = -8405198993435143622L;
42 jsr166 1.1
43 jsr166 1.12 private transient volatile long value;
44 jsr166 1.1
45     /**
46 jsr166 1.6 * Creates a new {@code AtomicDouble} with the given initial value.
47 jsr166 1.1 *
48     * @param initialValue the initial value
49     */
50     public AtomicDouble(double initialValue) {
51     value = doubleToRawLongBits(initialValue);
52     }
53    
54     /**
55 jsr166 1.6 * Creates a new {@code AtomicDouble} with initial value {@code 0.0}.
56 jsr166 1.1 */
57 jsr166 1.9 public AtomicDouble() {
58     // assert doubleToRawLongBits(0.0) == 0L;
59     }
60 jsr166 1.1
61     /**
62     * Gets the current value.
63     *
64     * @return the current value
65     */
66     public final double get() {
67     return longBitsToDouble(value);
68     }
69    
70     /**
71     * Sets to the given value.
72     *
73     * @param newValue the new value
74     */
75     public final void set(double newValue) {
76 jsr166 1.5 long next = doubleToRawLongBits(newValue);
77     value = next;
78 jsr166 1.1 }
79    
80     /**
81     * Eventually sets to the given value.
82     *
83     * @param newValue the new value
84     */
85     public final void lazySet(double newValue) {
86 jsr166 1.5 long next = doubleToRawLongBits(newValue);
87     unsafe.putOrderedLong(this, valueOffset, next);
88 jsr166 1.1 }
89    
90     /**
91     * Atomically sets to the given value and returns the old value.
92     *
93     * @param newValue the new value
94     * @return the previous value
95     */
96     public final double getAndSet(double newValue) {
97 jsr166 1.5 long next = doubleToRawLongBits(newValue);
98 jsr166 1.1 while (true) {
99 jsr166 1.5 long current = value;
100     if (unsafe.compareAndSwapLong(this, valueOffset, current, next))
101     return longBitsToDouble(current);
102 jsr166 1.1 }
103     }
104    
105     /**
106     * Atomically sets the value to the given updated value
107 jsr166 1.5 * if the current value is <a href="#bitEquals">bitwise equal</a>
108     * to the expected value.
109 jsr166 1.1 *
110     * @param expect the expected value
111     * @param update the new value
112 jsr166 1.5 * @return {@code true} if successful. False return indicates that
113     * the actual value was not bitwise equal to the expected value.
114 jsr166 1.1 */
115     public final boolean compareAndSet(double expect, double update) {
116     return unsafe.compareAndSwapLong(this, valueOffset,
117     doubleToRawLongBits(expect),
118     doubleToRawLongBits(update));
119     }
120    
121     /**
122     * Atomically sets the value to the given updated value
123 jsr166 1.5 * if the current value is <a href="#bitEquals">bitwise equal</a>
124     * to the expected value.
125 jsr166 1.1 *
126 jsr166 1.17 * <p><a
127 jsr166 1.9 * href="http://download.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/package-summary.html#Spurious">
128 jsr166 1.17 * May fail spuriously and does not provide ordering guarantees</a>,
129     * so is only rarely an appropriate alternative to {@code compareAndSet}.
130 jsr166 1.1 *
131     * @param expect the expected value
132     * @param update the new value
133 jsr166 1.5 * @return {@code true} if successful
134 jsr166 1.1 */
135     public final boolean weakCompareAndSet(double expect, double update) {
136     return compareAndSet(expect, update);
137     }
138    
139     /**
140     * Atomically adds the given value to the current value.
141     *
142     * @param delta the value to add
143     * @return the previous value
144     */
145     public final double getAndAdd(double delta) {
146     while (true) {
147 jsr166 1.5 long current = value;
148     double currentVal = longBitsToDouble(current);
149     double nextVal = currentVal + delta;
150     long next = doubleToRawLongBits(nextVal);
151     if (unsafe.compareAndSwapLong(this, valueOffset, current, next))
152     return currentVal;
153 jsr166 1.1 }
154     }
155    
156     /**
157     * Atomically adds the given value to the current value.
158     *
159     * @param delta the value to add
160     * @return the updated value
161     */
162     public final double addAndGet(double delta) {
163 jsr166 1.5 while (true) {
164     long current = value;
165     double currentVal = longBitsToDouble(current);
166     double nextVal = currentVal + delta;
167     long next = doubleToRawLongBits(nextVal);
168     if (unsafe.compareAndSwapLong(this, valueOffset, current, next))
169     return nextVal;
170 jsr166 1.1 }
171     }
172    
173     /**
174     * Returns the String representation of the current value.
175 jsr166 1.5 * @return the String representation of the current value
176 jsr166 1.1 */
177     public String toString() {
178     return Double.toString(get());
179     }
180    
181     /**
182     * Returns the value of this {@code AtomicDouble} as an {@code int}
183     * after a narrowing primitive conversion.
184     */
185     public int intValue() {
186 jsr166 1.9 return (int) get();
187 jsr166 1.1 }
188    
189     /**
190 jsr166 1.5 * Returns the value of this {@code AtomicDouble} as a {@code long}
191     * after a narrowing primitive conversion.
192 jsr166 1.1 */
193     public long longValue() {
194 jsr166 1.9 return (long) get();
195 jsr166 1.1 }
196    
197     /**
198     * Returns the value of this {@code AtomicDouble} as a {@code float}
199 jsr166 1.5 * after a narrowing primitive conversion.
200 jsr166 1.1 */
201     public float floatValue() {
202 jsr166 1.9 return (float) get();
203 jsr166 1.1 }
204    
205     /**
206 jsr166 1.5 * Returns the value of this {@code AtomicDouble} as a {@code double}.
207 jsr166 1.1 */
208     public double doubleValue() {
209     return get();
210     }
211    
212 jsr166 1.11 /**
213     * Saves the state to a stream (that is, serializes it).
214     *
215 jsr166 1.19 * @param s the stream
216     * @throws java.io.IOException if an I/O error occurs
217 jsr166 1.11 * @serialData The current value is emitted (a {@code double}).
218     */
219     private void writeObject(java.io.ObjectOutputStream s)
220 jsr166 1.13 throws java.io.IOException {
221 jsr166 1.11 s.defaultWriteObject();
222    
223     s.writeDouble(get());
224     }
225    
226     /**
227     * Reconstitutes the instance from a stream (that is, deserializes it).
228 jsr166 1.19 * @param s the stream
229     * @throws ClassNotFoundException if the class of a serialized object
230     * could not be found
231     * @throws java.io.IOException if an I/O error occurs
232 jsr166 1.11 */
233     private void readObject(java.io.ObjectInputStream s)
234     throws java.io.IOException, ClassNotFoundException {
235     s.defaultReadObject();
236    
237     set(s.readDouble());
238     }
239    
240 jsr166 1.5 // Unsafe mechanics
241     private static final sun.misc.Unsafe unsafe = getUnsafe();
242     private static final long valueOffset;
243    
244     static {
245     try {
246     valueOffset = unsafe.objectFieldOffset
247     (AtomicDouble.class.getDeclaredField("value"));
248     } catch (Exception ex) { throw new Error(ex); }
249     }
250    
251 jsr166 1.3 /**
252     * Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package.
253     * Replace with a simple call to Unsafe.getUnsafe when integrating
254     * into a jdk.
255     *
256     * @return a sun.misc.Unsafe
257     */
258     private static sun.misc.Unsafe getUnsafe() {
259     try {
260     return sun.misc.Unsafe.getUnsafe();
261 jsr166 1.14 } catch (SecurityException tryReflectionInstead) {}
262     try {
263     return java.security.AccessController.doPrivileged
264     (new java.security.PrivilegedExceptionAction<sun.misc.Unsafe>() {
265     public sun.misc.Unsafe run() throws Exception {
266     Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class;
267     for (java.lang.reflect.Field f : k.getDeclaredFields()) {
268     f.setAccessible(true);
269     Object x = f.get(null);
270     if (k.isInstance(x))
271     return k.cast(x);
272     }
273     throw new NoSuchFieldError("the Unsafe");
274     }});
275     } catch (java.security.PrivilegedActionException e) {
276     throw new RuntimeException("Could not initialize intrinsics",
277     e.getCause());
278 jsr166 1.3 }
279     }
280 jsr166 1.1 }