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