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.lang.invoke.MethodHandles; |
10 |
import java.lang.invoke.VarHandle; |
11 |
import java.util.function.BinaryOperator; |
12 |
import java.util.function.UnaryOperator; |
13 |
|
14 |
/** |
15 |
* An object reference that may be updated atomically. See the {@link |
16 |
* VarHandle} specification for descriptions of the properties of |
17 |
* atomic accesses. |
18 |
* @since 1.5 |
19 |
* @author Doug Lea |
20 |
* @param <V> The type of object referred to by this reference |
21 |
*/ |
22 |
public class AtomicReference<V> implements java.io.Serializable { |
23 |
private static final long serialVersionUID = -1848883965231344442L; |
24 |
private static final VarHandle VALUE; |
25 |
static { |
26 |
try { |
27 |
MethodHandles.Lookup l = MethodHandles.lookup(); |
28 |
VALUE = l.findVarHandle(AtomicReference.class, "value", Object.class); |
29 |
} catch (ReflectiveOperationException e) { |
30 |
throw new ExceptionInInitializerError(e); |
31 |
} |
32 |
} |
33 |
|
34 |
@SuppressWarnings("serial") // Conditionally serializable |
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 |
* Returns the current value, |
54 |
* with memory effects as specified by {@link VarHandle#getVolatile}. |
55 |
* |
56 |
* @return the current value |
57 |
*/ |
58 |
public final V get() { |
59 |
return value; |
60 |
} |
61 |
|
62 |
/** |
63 |
* Sets the value to {@code newValue}, |
64 |
* with memory effects as specified by {@link VarHandle#setVolatile}. |
65 |
* |
66 |
* @param newValue the new value |
67 |
*/ |
68 |
public final void set(V newValue) { |
69 |
value = newValue; |
70 |
} |
71 |
|
72 |
/** |
73 |
* Sets the value to {@code newValue}, |
74 |
* with memory effects as specified by {@link VarHandle#setRelease}. |
75 |
* |
76 |
* @param newValue the new value |
77 |
* @since 1.6 |
78 |
*/ |
79 |
public final void lazySet(V newValue) { |
80 |
VALUE.setRelease(this, newValue); |
81 |
} |
82 |
|
83 |
/** |
84 |
* Atomically sets the value to {@code newValue} |
85 |
* if the current value {@code == expectedValue}, |
86 |
* with memory effects as specified by {@link VarHandle#compareAndSet}. |
87 |
* |
88 |
* @param expectedValue the expected value |
89 |
* @param newValue the new value |
90 |
* @return {@code true} if successful. False return indicates that |
91 |
* the actual value was not equal to the expected value. |
92 |
*/ |
93 |
public final boolean compareAndSet(V expectedValue, V newValue) { |
94 |
return VALUE.compareAndSet(this, expectedValue, newValue); |
95 |
} |
96 |
|
97 |
/** |
98 |
* Possibly atomically sets the value to {@code newValue} |
99 |
* if the current value {@code == expectedValue}, |
100 |
* with memory effects as specified by {@link VarHandle#weakCompareAndSetPlain}. |
101 |
* |
102 |
* @deprecated This method has plain memory effects but the method |
103 |
* name implies volatile memory effects (see methods such as |
104 |
* {@link #compareAndExchange} and {@link #compareAndSet}). To avoid |
105 |
* confusion over plain or volatile memory effects it is recommended that |
106 |
* the method {@link #weakCompareAndSetPlain} be used instead. |
107 |
* |
108 |
* @param expectedValue the expected value |
109 |
* @param newValue the new value |
110 |
* @return {@code true} if successful |
111 |
* @see #weakCompareAndSetPlain |
112 |
*/ |
113 |
@Deprecated(since="9") |
114 |
public final boolean weakCompareAndSet(V expectedValue, V newValue) { |
115 |
return VALUE.weakCompareAndSetPlain(this, expectedValue, newValue); |
116 |
} |
117 |
|
118 |
/** |
119 |
* Possibly atomically sets the value to {@code newValue} |
120 |
* if the current value {@code == expectedValue}, |
121 |
* with memory effects as specified by {@link VarHandle#weakCompareAndSetPlain}. |
122 |
* |
123 |
* @param expectedValue the expected value |
124 |
* @param newValue the new value |
125 |
* @return {@code true} if successful |
126 |
* @since 9 |
127 |
*/ |
128 |
public final boolean weakCompareAndSetPlain(V expectedValue, V newValue) { |
129 |
return VALUE.weakCompareAndSetPlain(this, expectedValue, newValue); |
130 |
} |
131 |
|
132 |
/** |
133 |
* Atomically sets the value to {@code newValue} and returns the old value, |
134 |
* with memory effects as specified by {@link VarHandle#getAndSet}. |
135 |
* |
136 |
* @param newValue the new value |
137 |
* @return the previous value |
138 |
*/ |
139 |
@SuppressWarnings("unchecked") |
140 |
public final V getAndSet(V newValue) { |
141 |
return (V)VALUE.getAndSet(this, newValue); |
142 |
} |
143 |
|
144 |
/** |
145 |
* Atomically updates (with memory effects as specified by {@link |
146 |
* VarHandle#compareAndSet}) the current value with the results of |
147 |
* applying the given function, returning the previous value. The |
148 |
* function should be side-effect-free, since it may be re-applied |
149 |
* when attempted updates fail due to contention among threads. |
150 |
* |
151 |
* @param updateFunction a side-effect-free function |
152 |
* @return the previous value |
153 |
* @since 1.8 |
154 |
*/ |
155 |
public final V getAndUpdate(UnaryOperator<V> updateFunction) { |
156 |
V prev = get(), next = null; |
157 |
for (boolean haveNext = false;;) { |
158 |
if (!haveNext) |
159 |
next = updateFunction.apply(prev); |
160 |
if (weakCompareAndSetVolatile(prev, next)) |
161 |
return prev; |
162 |
haveNext = (prev == (prev = get())); |
163 |
} |
164 |
} |
165 |
|
166 |
/** |
167 |
* Atomically updates (with memory effects as specified by {@link |
168 |
* VarHandle#compareAndSet}) the current value with the results of |
169 |
* applying the given function, returning the updated value. The |
170 |
* function should be side-effect-free, since it may be re-applied |
171 |
* when attempted updates fail due to contention among threads. |
172 |
* |
173 |
* @param updateFunction a side-effect-free function |
174 |
* @return the updated value |
175 |
* @since 1.8 |
176 |
*/ |
177 |
public final V updateAndGet(UnaryOperator<V> updateFunction) { |
178 |
V prev = get(), next = null; |
179 |
for (boolean haveNext = false;;) { |
180 |
if (!haveNext) |
181 |
next = updateFunction.apply(prev); |
182 |
if (weakCompareAndSetVolatile(prev, next)) |
183 |
return next; |
184 |
haveNext = (prev == (prev = get())); |
185 |
} |
186 |
} |
187 |
|
188 |
/** |
189 |
* Atomically updates (with memory effects as specified by {@link |
190 |
* VarHandle#compareAndSet}) the current value with the results of |
191 |
* applying the given function to the current and given values, |
192 |
* returning the previous value. The function should be |
193 |
* side-effect-free, since it may be re-applied when attempted |
194 |
* updates fail due to contention among threads. The function is |
195 |
* applied with the current value as its first argument, and the |
196 |
* given update as the second argument. |
197 |
* |
198 |
* @param x the update value |
199 |
* @param accumulatorFunction a side-effect-free function of two arguments |
200 |
* @return the previous value |
201 |
* @since 1.8 |
202 |
*/ |
203 |
public final V getAndAccumulate(V x, |
204 |
BinaryOperator<V> accumulatorFunction) { |
205 |
V prev = get(), next = null; |
206 |
for (boolean haveNext = false;;) { |
207 |
if (!haveNext) |
208 |
next = accumulatorFunction.apply(prev, x); |
209 |
if (weakCompareAndSetVolatile(prev, next)) |
210 |
return prev; |
211 |
haveNext = (prev == (prev = get())); |
212 |
} |
213 |
} |
214 |
|
215 |
/** |
216 |
* Atomically updates (with memory effects as specified by {@link |
217 |
* VarHandle#compareAndSet}) the current value with the results of |
218 |
* applying the given function to the current and given values, |
219 |
* returning the updated value. The function should be |
220 |
* side-effect-free, since it may be re-applied when attempted |
221 |
* updates fail due to contention among threads. The function is |
222 |
* applied with the current value as its first argument, and the |
223 |
* given update as the second argument. |
224 |
* |
225 |
* @param x the update value |
226 |
* @param accumulatorFunction a side-effect-free function of two arguments |
227 |
* @return the updated value |
228 |
* @since 1.8 |
229 |
*/ |
230 |
public final V accumulateAndGet(V x, |
231 |
BinaryOperator<V> accumulatorFunction) { |
232 |
V prev = get(), next = null; |
233 |
for (boolean haveNext = false;;) { |
234 |
if (!haveNext) |
235 |
next = accumulatorFunction.apply(prev, x); |
236 |
if (weakCompareAndSetVolatile(prev, next)) |
237 |
return next; |
238 |
haveNext = (prev == (prev = get())); |
239 |
} |
240 |
} |
241 |
|
242 |
/** |
243 |
* Returns the String representation of the current value. |
244 |
* @return the String representation of the current value |
245 |
*/ |
246 |
public String toString() { |
247 |
return String.valueOf(get()); |
248 |
} |
249 |
|
250 |
// jdk9 |
251 |
|
252 |
/** |
253 |
* Returns the current value, with memory semantics of reading as |
254 |
* if the variable was declared non-{@code volatile}. |
255 |
* |
256 |
* @return the value |
257 |
* @since 9 |
258 |
*/ |
259 |
public final V getPlain() { |
260 |
return (V)VALUE.get(this); |
261 |
} |
262 |
|
263 |
/** |
264 |
* Sets the value to {@code newValue}, with memory semantics |
265 |
* of setting as if the variable was declared non-{@code volatile} |
266 |
* and non-{@code final}. |
267 |
* |
268 |
* @param newValue the new value |
269 |
* @since 9 |
270 |
*/ |
271 |
public final void setPlain(V newValue) { |
272 |
VALUE.set(this, newValue); |
273 |
} |
274 |
|
275 |
/** |
276 |
* Returns the current value, |
277 |
* with memory effects as specified by {@link VarHandle#getOpaque}. |
278 |
* |
279 |
* @return the value |
280 |
* @since 9 |
281 |
*/ |
282 |
public final V getOpaque() { |
283 |
return (V)VALUE.getOpaque(this); |
284 |
} |
285 |
|
286 |
/** |
287 |
* Sets the value to {@code newValue}, |
288 |
* with memory effects as specified by {@link VarHandle#setOpaque}. |
289 |
* |
290 |
* @param newValue the new value |
291 |
* @since 9 |
292 |
*/ |
293 |
public final void setOpaque(V newValue) { |
294 |
VALUE.setOpaque(this, newValue); |
295 |
} |
296 |
|
297 |
/** |
298 |
* Returns the current value, |
299 |
* with memory effects as specified by {@link VarHandle#getAcquire}. |
300 |
* |
301 |
* @return the value |
302 |
* @since 9 |
303 |
*/ |
304 |
public final V getAcquire() { |
305 |
return (V)VALUE.getAcquire(this); |
306 |
} |
307 |
|
308 |
/** |
309 |
* Sets the value to {@code newValue}, |
310 |
* with memory effects as specified by {@link VarHandle#setRelease}. |
311 |
* |
312 |
* @param newValue the new value |
313 |
* @since 9 |
314 |
*/ |
315 |
public final void setRelease(V newValue) { |
316 |
VALUE.setRelease(this, newValue); |
317 |
} |
318 |
|
319 |
/** |
320 |
* Atomically sets the value to {@code newValue} if the current value, |
321 |
* referred to as the <em>witness value</em>, {@code == expectedValue}, |
322 |
* with memory effects as specified by |
323 |
* {@link VarHandle#compareAndExchange}. |
324 |
* |
325 |
* @param expectedValue the expected value |
326 |
* @param newValue the new value |
327 |
* @return the witness value, which will be the same as the |
328 |
* expected value if successful |
329 |
* @since 9 |
330 |
*/ |
331 |
public final V compareAndExchange(V expectedValue, V newValue) { |
332 |
return (V)VALUE.compareAndExchange(this, expectedValue, newValue); |
333 |
} |
334 |
|
335 |
/** |
336 |
* Atomically sets the value to {@code newValue} if the current value, |
337 |
* referred to as the <em>witness value</em>, {@code == expectedValue}, |
338 |
* with memory effects as specified by |
339 |
* {@link VarHandle#compareAndExchangeAcquire}. |
340 |
* |
341 |
* @param expectedValue the expected value |
342 |
* @param newValue the new value |
343 |
* @return the witness value, which will be the same as the |
344 |
* expected value if successful |
345 |
* @since 9 |
346 |
*/ |
347 |
public final V compareAndExchangeAcquire(V expectedValue, V newValue) { |
348 |
return (V)VALUE.compareAndExchangeAcquire(this, expectedValue, newValue); |
349 |
} |
350 |
|
351 |
/** |
352 |
* Atomically sets the value to {@code newValue} if the current value, |
353 |
* referred to as the <em>witness value</em>, {@code == expectedValue}, |
354 |
* with memory effects as specified by |
355 |
* {@link VarHandle#compareAndExchangeRelease}. |
356 |
* |
357 |
* @param expectedValue the expected value |
358 |
* @param newValue the new value |
359 |
* @return the witness value, which will be the same as the |
360 |
* expected value if successful |
361 |
* @since 9 |
362 |
*/ |
363 |
public final V compareAndExchangeRelease(V expectedValue, V newValue) { |
364 |
return (V)VALUE.compareAndExchangeRelease(this, expectedValue, newValue); |
365 |
} |
366 |
|
367 |
/** |
368 |
* Possibly atomically sets the value to {@code newValue} |
369 |
* if the current value {@code == expectedValue}, |
370 |
* with memory effects as specified by |
371 |
* {@link VarHandle#weakCompareAndSet}. |
372 |
* |
373 |
* @param expectedValue the expected value |
374 |
* @param newValue the new value |
375 |
* @return {@code true} if successful |
376 |
* @since 9 |
377 |
*/ |
378 |
public final boolean weakCompareAndSetVolatile(V expectedValue, V newValue) { |
379 |
return VALUE.weakCompareAndSet(this, expectedValue, newValue); |
380 |
} |
381 |
|
382 |
/** |
383 |
* Possibly atomically sets the value to {@code newValue} |
384 |
* if the current value {@code == expectedValue}, |
385 |
* with memory effects as specified by |
386 |
* {@link VarHandle#weakCompareAndSetAcquire}. |
387 |
* |
388 |
* @param expectedValue the expected value |
389 |
* @param newValue the new value |
390 |
* @return {@code true} if successful |
391 |
* @since 9 |
392 |
*/ |
393 |
public final boolean weakCompareAndSetAcquire(V expectedValue, V newValue) { |
394 |
return VALUE.weakCompareAndSetAcquire(this, expectedValue, newValue); |
395 |
} |
396 |
|
397 |
/** |
398 |
* Possibly atomically sets the value to {@code newValue} |
399 |
* if the current value {@code == expectedValue}, |
400 |
* with memory effects as specified by |
401 |
* {@link VarHandle#weakCompareAndSetRelease}. |
402 |
* |
403 |
* @param expectedValue the expected value |
404 |
* @param newValue the new value |
405 |
* @return {@code true} if successful |
406 |
* @since 9 |
407 |
*/ |
408 |
public final boolean weakCompareAndSetRelease(V expectedValue, V newValue) { |
409 |
return VALUE.weakCompareAndSetRelease(this, expectedValue, newValue); |
410 |
} |
411 |
|
412 |
} |