ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/atomic/AtomicReference.java
Revision: 1.56
Committed: Thu Oct 17 01:51:38 2019 UTC (4 years, 7 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.55: +1 -0 lines
Log Message:
8232230: Suppress warnings on non-serializable non-transient instance fields in java.util.concurrent

File Contents

# Content
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 }