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 |
4 |
* http://creativecommons.org/publicdomain/zero/1.0/ |
5 |
*/ |
6 |
|
7 |
package java.util.concurrent.atomic; |
8 |
|
9 |
import java.util.function.BinaryOperator; |
10 |
import java.util.function.UnaryOperator; |
11 |
|
12 |
/** |
13 |
* An object reference that may be updated atomically. See the {@link |
14 |
* java.util.concurrent.atomic} package specification for description |
15 |
* of the properties of atomic variables. |
16 |
* @since 1.5 |
17 |
* @author Doug Lea |
18 |
* @param <V> The type of object referred to by this reference |
19 |
*/ |
20 |
public class AtomicReference<V> implements java.io.Serializable { |
21 |
private static final long serialVersionUID = -1848883965231344442L; |
22 |
|
23 |
private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); |
24 |
private static final long VALUE; |
25 |
|
26 |
static { |
27 |
try { |
28 |
VALUE = U.objectFieldOffset |
29 |
(AtomicReference.class.getDeclaredField("value")); |
30 |
} catch (ReflectiveOperationException e) { |
31 |
throw new Error(e); |
32 |
} |
33 |
} |
34 |
|
35 |
private volatile V value; |
36 |
|
37 |
/** |
38 |
* Creates a new AtomicReference with the given initial value. |
39 |
* |
40 |
* @param initialValue the initial value |
41 |
*/ |
42 |
public AtomicReference(V initialValue) { |
43 |
value = initialValue; |
44 |
} |
45 |
|
46 |
/** |
47 |
* Creates a new AtomicReference with null initial value. |
48 |
*/ |
49 |
public AtomicReference() { |
50 |
} |
51 |
|
52 |
/** |
53 |
* Gets the current value. |
54 |
* |
55 |
* @return the current value |
56 |
*/ |
57 |
public final V get() { |
58 |
return value; |
59 |
} |
60 |
|
61 |
/** |
62 |
* Sets to the given value. |
63 |
* |
64 |
* @param newValue the new value |
65 |
*/ |
66 |
public final void set(V newValue) { |
67 |
value = newValue; |
68 |
} |
69 |
|
70 |
/** |
71 |
* Eventually sets to the given value. |
72 |
* |
73 |
* @param newValue the new value |
74 |
* @since 1.6 |
75 |
*/ |
76 |
public final void lazySet(V newValue) { |
77 |
U.putOrderedObject(this, VALUE, newValue); |
78 |
} |
79 |
|
80 |
/** |
81 |
* Atomically sets the value to the given updated value |
82 |
* if the current value {@code ==} the expected value. |
83 |
* @param expect the expected value |
84 |
* @param update the new value |
85 |
* @return {@code true} if successful. False return indicates that |
86 |
* the actual value was not equal to the expected value. |
87 |
*/ |
88 |
public final boolean compareAndSet(V expect, V update) { |
89 |
return U.compareAndSwapObject(this, VALUE, expect, update); |
90 |
} |
91 |
|
92 |
/** |
93 |
* Atomically sets the value to the given updated value |
94 |
* if the current value {@code ==} the expected value. |
95 |
* |
96 |
* <p><a href="package-summary.html#weakCompareAndSet">May fail |
97 |
* spuriously and does not provide ordering guarantees</a>, so is |
98 |
* only rarely an appropriate alternative to {@code compareAndSet}. |
99 |
* |
100 |
* @param expect the expected value |
101 |
* @param update the new value |
102 |
* @return {@code true} if successful |
103 |
*/ |
104 |
public final boolean weakCompareAndSet(V expect, V update) { |
105 |
return U.compareAndSwapObject(this, VALUE, expect, update); |
106 |
} |
107 |
|
108 |
/** |
109 |
* Atomically sets to the given value and returns the old value. |
110 |
* |
111 |
* @param newValue the new value |
112 |
* @return the previous value |
113 |
*/ |
114 |
@SuppressWarnings("unchecked") |
115 |
public final V getAndSet(V newValue) { |
116 |
return (V)U.getAndSetObject(this, VALUE, newValue); |
117 |
} |
118 |
|
119 |
/** |
120 |
* Atomically updates the current value with the results of |
121 |
* applying the given function, returning the previous value. The |
122 |
* function should be side-effect-free, since it may be re-applied |
123 |
* when attempted updates fail due to contention among threads. |
124 |
* |
125 |
* @param updateFunction a side-effect-free function |
126 |
* @return the previous value |
127 |
* @since 1.8 |
128 |
*/ |
129 |
public final V getAndUpdate(UnaryOperator<V> updateFunction) { |
130 |
V prev, next; |
131 |
do { |
132 |
prev = get(); |
133 |
next = updateFunction.apply(prev); |
134 |
} while (!compareAndSet(prev, next)); |
135 |
return prev; |
136 |
} |
137 |
|
138 |
/** |
139 |
* Atomically updates the current value with the results of |
140 |
* applying the given function, returning the updated value. The |
141 |
* function should be side-effect-free, since it may be re-applied |
142 |
* when attempted updates fail due to contention among threads. |
143 |
* |
144 |
* @param updateFunction a side-effect-free function |
145 |
* @return the updated value |
146 |
* @since 1.8 |
147 |
*/ |
148 |
public final V updateAndGet(UnaryOperator<V> updateFunction) { |
149 |
V prev, next; |
150 |
do { |
151 |
prev = get(); |
152 |
next = updateFunction.apply(prev); |
153 |
} while (!compareAndSet(prev, next)); |
154 |
return next; |
155 |
} |
156 |
|
157 |
/** |
158 |
* Atomically updates the current value with the results of |
159 |
* applying the given function to the current and given values, |
160 |
* returning the previous value. The function should be |
161 |
* side-effect-free, since it may be re-applied when attempted |
162 |
* updates fail due to contention among threads. The function |
163 |
* is applied with the current value as its first argument, |
164 |
* and the given update as the second argument. |
165 |
* |
166 |
* @param x the update value |
167 |
* @param accumulatorFunction a side-effect-free function of two arguments |
168 |
* @return the previous value |
169 |
* @since 1.8 |
170 |
*/ |
171 |
public final V getAndAccumulate(V x, |
172 |
BinaryOperator<V> accumulatorFunction) { |
173 |
V prev, next; |
174 |
do { |
175 |
prev = get(); |
176 |
next = accumulatorFunction.apply(prev, x); |
177 |
} while (!compareAndSet(prev, next)); |
178 |
return prev; |
179 |
} |
180 |
|
181 |
/** |
182 |
* Atomically updates the current value with the results of |
183 |
* applying the given function to the current and given values, |
184 |
* returning the updated value. The function should be |
185 |
* side-effect-free, since it may be re-applied when attempted |
186 |
* updates fail due to contention among threads. The function |
187 |
* is applied with the current value as its first argument, |
188 |
* and the given update as the second argument. |
189 |
* |
190 |
* @param x the update value |
191 |
* @param accumulatorFunction a side-effect-free function of two arguments |
192 |
* @return the updated value |
193 |
* @since 1.8 |
194 |
*/ |
195 |
public final V accumulateAndGet(V x, |
196 |
BinaryOperator<V> accumulatorFunction) { |
197 |
V prev, next; |
198 |
do { |
199 |
prev = get(); |
200 |
next = accumulatorFunction.apply(prev, x); |
201 |
} while (!compareAndSet(prev, next)); |
202 |
return next; |
203 |
} |
204 |
|
205 |
/** |
206 |
* Returns the String representation of the current value. |
207 |
* @return the String representation of the current value |
208 |
*/ |
209 |
public String toString() { |
210 |
return String.valueOf(get()); |
211 |
} |
212 |
|
213 |
} |