1 |
|
/* |
2 |
< |
* Written by Doug Lea with assistance from members of JCP JSR-166 |
3 |
< |
* Expert Group and released to the public domain, as explained at |
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 |
|
* http://creativecommons.org/publicdomain/zero/1.0/ |
6 |
|
*/ |
7 |
|
|
13 |
|
/** |
14 |
|
* A {@code double} value that may be updated atomically. See the |
15 |
|
* {@link java.util.concurrent.atomic} package specification for |
16 |
< |
* description of the properties of atomic variables. An |
17 |
< |
* {@code AtomicDouble} is used in applications such as atomically |
18 |
< |
* incremented sequence numbers, and cannot be used as a replacement |
19 |
< |
* for a {@link java.lang.Double}. However, this class does extend |
20 |
< |
* {@code Number} to allow uniform access by tools and utilities that |
20 |
< |
* deal with numerically-based classes. |
16 |
> |
* description of the properties of atomic variables. An {@code |
17 |
> |
* AtomicDouble} is used in applications such as atomic summation, and |
18 |
> |
* cannot be used as a replacement for a {@link Double}. However, |
19 |
> |
* this class does extend {@code Number} to allow uniform access by |
20 |
> |
* tools and utilities that deal with numerically-based classes. |
21 |
|
* |
22 |
+ |
* <p>This class differs from the primitive double {@code ==} operator |
23 |
+ |
* and from {@link Double#equals} in that it uses purely bitwise |
24 |
+ |
* equality in methods such as {@link #compareAndSet}, as if |
25 |
+ |
* implemented by: |
26 |
+ |
* <pre> {@code |
27 |
+ |
* boolean bitEquals(double x, double y) { |
28 |
+ |
* long xBits = Double.doubleToRawLongBits(x); |
29 |
+ |
* long yBits = Double.doubleToRawLongBits(y); |
30 |
+ |
* return xBits == yBits; |
31 |
+ |
* }}</pre> |
32 |
+ |
* |
33 |
|
* @since 1.5 |
34 |
|
* @author Doug Lea |
35 |
+ |
* @author Martin Buchholz |
36 |
|
*/ |
37 |
|
public class AtomicDouble extends Number implements java.io.Serializable { |
38 |
|
private static final long serialVersionUID = 1927816293512124184L; |
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 native boolean VMSupportsCS8(); |
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 |
|
|
66 |
|
static { |
67 |
|
try { |
124 |
|
long newBits = doubleToRawLongBits(newValue); |
125 |
|
while (true) { |
126 |
|
long currentBits = value; |
127 |
< |
if (compareAndSet(currentBits, newBits)) |
127 |
> |
if (unsafe.compareAndSwapLong(this, valueOffset, |
128 |
> |
currentBits, newBits)) |
129 |
|
return longBitsToDouble(currentBits); |
130 |
|
} |
131 |
|
} |
171 |
|
while (true) { |
172 |
|
long currentBits = value; |
173 |
|
long nextBits = doubleToRawLongBits(longBitsToDouble(currentBits) + delta); |
174 |
< |
if (compareAndSet(currentBits, nextBits)) |
174 |
> |
if (unsafe.compareAndSwapLong(this, valueOffset, |
175 |
> |
currentBits, nextBits)) |
176 |
|
return longBitsToDouble(currentBits); |
177 |
|
} |
178 |
|
} |