1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 *
4 * This code is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 only, as
6 * published by the Free Software Foundation. Oracle designates this
7 * particular file as subject to the "Classpath" exception as provided
8 * by Oracle in the LICENSE file that accompanied this code.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 */
24
25 /*
26 * This file is available under and governed by the GNU General Public
27 * License version 2 only, as published by the Free Software Foundation.
28 * However, the following notice accompanied the original version of this
29 * file:
30 *
31 * Written by Doug Lea with assistance from members of JCP JSR-166
32 * Expert Group and released to the public domain, as explained at
33 * http://creativecommons.org/publicdomain/zero/1.0/
34 */
35
36 package java.util.concurrent.atomic;
37
38 import java.lang.invoke.MethodHandles;
39 import java.lang.invoke.VarHandle;
40 import java.util.function.BinaryOperator;
41 import java.util.function.UnaryOperator;
42
43 /**
44 * An object reference that may be updated atomically. See the {@link
45 * VarHandle} specification for descriptions of the properties of
46 * atomic accesses.
47 * @since 1.5
48 * @author Doug Lea
49 * @param <V> The type of object referred to by this reference
50 */
51 public class AtomicReference<V> implements java.io.Serializable {
52 private static final long serialVersionUID = -1848883965231344442L;
53 private static final VarHandle VALUE;
54 static {
55 try {
56 MethodHandles.Lookup l = MethodHandles.lookup();
57 VALUE = l.findVarHandle(AtomicReference.class, "value", Object.class);
58 } catch (ReflectiveOperationException e) {
59 throw new ExceptionInInitializerError(e);
60 }
61 }
62
63 private volatile V value;
64
65 /**
66 * Creates a new AtomicReference with the given initial value.
67 *
68 * @param initialValue the initial value
69 */
70 public AtomicReference(V initialValue) {
71 value = initialValue;
72 }
73
74 /**
75 * Creates a new AtomicReference with null initial value.
76 */
77 public AtomicReference() {
78 }
79
80 /**
81 * Returns the current value,
82 * with memory effects as specified by {@link VarHandle#getVolatile}.
83 *
84 * @return the current value
85 */
86 public final V get() {
87 return value;
88 }
89
90 /**
91 * Sets the value to {@code newValue},
92 * with memory effects as specified by {@link VarHandle#setVolatile}.
93 *
94 * @param newValue the new value
95 */
96 public final void set(V newValue) {
97 value = newValue;
98 }
99
100 /**
101 * Sets the value to {@code newValue},
102 * with memory effects as specified by {@link VarHandle#setRelease}.
103 *
104 * @param newValue the new value
105 * @since 1.6
106 */
107 public final void lazySet(V newValue) {
108 VALUE.setRelease(this, newValue);
109 }
110
111 /**
112 * Atomically sets the value to {@code newValue}
113 * if the current value {@code == expectedValue},
114 * with memory effects as specified by {@link VarHandle#compareAndSet}.
115 *
116 * @param expectedValue the expected value
117 * @param newValue the new value
118 * @return {@code true} if successful. False return indicates that
119 * the actual value was not equal to the expected value.
120 */
121 public final boolean compareAndSet(V expectedValue, V newValue) {
122 return VALUE.compareAndSet(this, expectedValue, newValue);
123 }
124
125 /**
126 * Possibly atomically sets the value to {@code newValue}
127 * if the current value {@code == expectedValue},
128 * with memory effects as specified by {@link VarHandle#weakCompareAndSetPlain}.
129 *
130 * @deprecated This method has plain memory effects but the method
131 * name implies volatile memory effects (see methods such as
132 * {@link #compareAndExchange} and {@link #compareAndSet}). To avoid
133 * confusion over plain or volatile memory effects it is recommended that
134 * the method {@link #weakCompareAndSetPlain} be used instead.
135 *
136 * @param expectedValue the expected value
137 * @param newValue the new value
138 * @return {@code true} if successful
139 * @see #weakCompareAndSetPlain
140 */
141 @Deprecated(since="9")
142 public final boolean weakCompareAndSet(V expectedValue, V newValue) {
143 return VALUE.weakCompareAndSetPlain(this, expectedValue, newValue);
144 }
145
146 /**
147 * Possibly atomically sets the value to {@code newValue}
148 * if the current value {@code == expectedValue},
149 * with memory effects as specified by {@link VarHandle#weakCompareAndSetPlain}.
150 *
151 * @param expectedValue the expected value
152 * @param newValue the new value
153 * @return {@code true} if successful
154 * @since 9
155 */
156 public final boolean weakCompareAndSetPlain(V expectedValue, V newValue) {
157 return VALUE.weakCompareAndSetPlain(this, expectedValue, newValue);
158 }
159
160 /**
161 * Atomically sets the value to {@code newValue} and returns the old value,
162 * with memory effects as specified by {@link VarHandle#getAndSet}.
163 *
164 * @param newValue the new value
165 * @return the previous value
166 */
167 @SuppressWarnings("unchecked")
168 public final V getAndSet(V newValue) {
169 return (V)VALUE.getAndSet(this, newValue);
170 }
171
172 /**
173 * Atomically updates (with memory effects as specified by {@link
174 * VarHandle#compareAndSet}) the current value with the results of
175 * applying the given function, returning the previous value. The
176 * function should be side-effect-free, since it may be re-applied
177 * when attempted updates fail due to contention among threads.
178 *
179 * @param updateFunction a side-effect-free function
180 * @return the previous value
181 * @since 1.8
182 */
183 public final V getAndUpdate(UnaryOperator<V> updateFunction) {
184 V prev = get(), next = null;
185 for (boolean haveNext = false;;) {
186 if (!haveNext)
187 next = updateFunction.apply(prev);
188 if (weakCompareAndSetVolatile(prev, next))
189 return prev;
190 haveNext = (prev == (prev = get()));
191 }
192 }
193
194 /**
195 * Atomically updates (with memory effects as specified by {@link
196 * VarHandle#compareAndSet}) the current value with the results of
197 * applying the given function, returning the updated value. The
198 * function should be side-effect-free, since it may be re-applied
199 * when attempted updates fail due to contention among threads.
200 *
201 * @param updateFunction a side-effect-free function
202 * @return the updated value
203 * @since 1.8
204 */
205 public final V updateAndGet(UnaryOperator<V> updateFunction) {
206 V prev = get(), next = null;
207 for (boolean haveNext = false;;) {
208 if (!haveNext)
209 next = updateFunction.apply(prev);
210 if (weakCompareAndSetVolatile(prev, next))
211 return next;
212 haveNext = (prev == (prev = get()));
213 }
214 }
215
216 /**
217 * Atomically updates (with memory effects as specified by {@link
218 * VarHandle#compareAndSet}) the current value with the results of
219 * applying the given function to the current and given values,
220 * returning the previous value. The function should be
221 * side-effect-free, since it may be re-applied when attempted
222 * updates fail due to contention among threads. The function is
223 * applied with the current value as its first argument, and the
224 * given update as the second argument.
225 *
226 * @param x the update value
227 * @param accumulatorFunction a side-effect-free function of two arguments
228 * @return the previous value
229 * @since 1.8
230 */
231 public final V getAndAccumulate(V x,
232 BinaryOperator<V> accumulatorFunction) {
233 V prev = get(), next = null;
234 for (boolean haveNext = false;;) {
235 if (!haveNext)
236 next = accumulatorFunction.apply(prev, x);
237 if (weakCompareAndSetVolatile(prev, next))
238 return prev;
239 haveNext = (prev == (prev = get()));
240 }
241 }
242
243 /**
244 * Atomically updates (with memory effects as specified by {@link
245 * VarHandle#compareAndSet}) the current value with the results of
246 * applying the given function to the current and given values,
247 * returning the updated value. The function should be
248 * side-effect-free, since it may be re-applied when attempted
249 * updates fail due to contention among threads. The function is
250 * applied with the current value as its first argument, and the
251 * given update as the second argument.
252 *
253 * @param x the update value
254 * @param accumulatorFunction a side-effect-free function of two arguments
255 * @return the updated value
256 * @since 1.8
257 */
258 public final V accumulateAndGet(V x,
259 BinaryOperator<V> accumulatorFunction) {
260 V prev = get(), next = null;
261 for (boolean haveNext = false;;) {
262 if (!haveNext)
263 next = accumulatorFunction.apply(prev, x);
264 if (weakCompareAndSetVolatile(prev, next))
265 return next;
266 haveNext = (prev == (prev = get()));
267 }
268 }
269
270 /**
271 * Returns the String representation of the current value.
272 * @return the String representation of the current value
273 */
274 public String toString() {
275 return String.valueOf(get());
276 }
277
278 // jdk9
279
280 /**
281 * Returns the current value, with memory semantics of reading as
282 * if the variable was declared non-{@code volatile}.
283 *
284 * @return the value
285 * @since 9
286 */
287 public final V getPlain() {
288 return (V)VALUE.get(this);
289 }
290
291 /**
292 * Sets the value to {@code newValue}, with memory semantics
293 * of setting as if the variable was declared non-{@code volatile}
294 * and non-{@code final}.
295 *
296 * @param newValue the new value
297 * @since 9
298 */
299 public final void setPlain(V newValue) {
300 VALUE.set(this, newValue);
301 }
302
303 /**
304 * Returns the current value,
305 * with memory effects as specified by {@link VarHandle#getOpaque}.
306 *
307 * @return the value
308 * @since 9
309 */
310 public final V getOpaque() {
311 return (V)VALUE.getOpaque(this);
312 }
313
314 /**
315 * Sets the value to {@code newValue},
316 * with memory effects as specified by {@link VarHandle#setOpaque}.
317 *
318 * @param newValue the new value
319 * @since 9
320 */
321 public final void setOpaque(V newValue) {
322 VALUE.setOpaque(this, newValue);
323 }
324
325 /**
326 * Returns the current value,
327 * with memory effects as specified by {@link VarHandle#getAcquire}.
328 *
329 * @return the value
330 * @since 9
331 */
332 public final V getAcquire() {
333 return (V)VALUE.getAcquire(this);
334 }
335
336 /**
337 * Sets the value to {@code newValue},
338 * with memory effects as specified by {@link VarHandle#setRelease}.
339 *
340 * @param newValue the new value
341 * @since 9
342 */
343 public final void setRelease(V newValue) {
344 VALUE.setRelease(this, newValue);
345 }
346
347 /**
348 * Atomically sets the value to {@code newValue} if the current value,
349 * referred to as the <em>witness value</em>, {@code == expectedValue},
350 * with memory effects as specified by
351 * {@link VarHandle#compareAndExchange}.
352 *
353 * @param expectedValue the expected value
354 * @param newValue the new value
355 * @return the witness value, which will be the same as the
356 * expected value if successful
357 * @since 9
358 */
359 public final V compareAndExchange(V expectedValue, V newValue) {
360 return (V)VALUE.compareAndExchange(this, expectedValue, newValue);
361 }
362
363 /**
364 * Atomically sets the value to {@code newValue} if the current value,
365 * referred to as the <em>witness value</em>, {@code == expectedValue},
366 * with memory effects as specified by
367 * {@link VarHandle#compareAndExchangeAcquire}.
368 *
369 * @param expectedValue the expected value
370 * @param newValue the new value
371 * @return the witness value, which will be the same as the
372 * expected value if successful
373 * @since 9
374 */
375 public final V compareAndExchangeAcquire(V expectedValue, V newValue) {
376 return (V)VALUE.compareAndExchangeAcquire(this, expectedValue, newValue);
377 }
378
379 /**
380 * Atomically sets the value to {@code newValue} if the current value,
381 * referred to as the <em>witness value</em>, {@code == expectedValue},
382 * with memory effects as specified by
383 * {@link VarHandle#compareAndExchangeRelease}.
384 *
385 * @param expectedValue the expected value
386 * @param newValue the new value
387 * @return the witness value, which will be the same as the
388 * expected value if successful
389 * @since 9
390 */
391 public final V compareAndExchangeRelease(V expectedValue, V newValue) {
392 return (V)VALUE.compareAndExchangeRelease(this, expectedValue, newValue);
393 }
394
395 /**
396 * Possibly atomically sets the value to {@code newValue}
397 * if the current value {@code == expectedValue},
398 * with memory effects as specified by
399 * {@link VarHandle#weakCompareAndSet}.
400 *
401 * @param expectedValue the expected value
402 * @param newValue the new value
403 * @return {@code true} if successful
404 * @since 9
405 */
406 public final boolean weakCompareAndSetVolatile(V expectedValue, V newValue) {
407 return VALUE.weakCompareAndSet(this, expectedValue, newValue);
408 }
409
410 /**
411 * Possibly atomically sets the value to {@code newValue}
412 * if the current value {@code == expectedValue},
413 * with memory effects as specified by
414 * {@link VarHandle#weakCompareAndSetAcquire}.
415 *
416 * @param expectedValue the expected value
417 * @param newValue the new value
418 * @return {@code true} if successful
419 * @since 9
420 */
421 public final boolean weakCompareAndSetAcquire(V expectedValue, V newValue) {
422 return VALUE.weakCompareAndSetAcquire(this, expectedValue, newValue);
423 }
424
425 /**
426 * Possibly atomically sets the value to {@code newValue}
427 * if the current value {@code == expectedValue},
428 * with memory effects as specified by
429 * {@link VarHandle#weakCompareAndSetRelease}.
430 *
431 * @param expectedValue the expected value
432 * @param newValue the new value
433 * @return {@code true} if successful
434 * @since 9
435 */
436 public final boolean weakCompareAndSetRelease(V expectedValue, V newValue) {
437 return VALUE.weakCompareAndSetRelease(this, expectedValue, newValue);
438 }
439
440 }
441