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 */ AtomicReference(V initialValue)70 public AtomicReference(V initialValue) { 71 value = initialValue; 72 } 73 74 /** 75 * Creates a new AtomicReference with null initial value. 76 */ AtomicReference()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 */ get()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 */ set(V newValue)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 */ lazySet(V newValue)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 */ compareAndSet(V expectedValue, V newValue)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") weakCompareAndSet(V expectedValue, V newValue)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 */ weakCompareAndSetPlain(V expectedValue, V newValue)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") getAndSet(V newValue)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 */ getAndUpdate(UnaryOperator<V> updateFunction)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 */ updateAndGet(UnaryOperator<V> updateFunction)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 */ getAndAccumulate(V x, BinaryOperator<V> accumulatorFunction)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 */ accumulateAndGet(V x, BinaryOperator<V> accumulatorFunction)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 */ toString()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 */ getPlain()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 */ setPlain(V newValue)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 */ getOpaque()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 */ setOpaque(V newValue)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 */ getAcquire()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 */ setRelease(V newValue)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 */ compareAndExchange(V expectedValue, V newValue)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 */ compareAndExchangeAcquire(V expectedValue, V newValue)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 */ compareAndExchangeRelease(V expectedValue, V newValue)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 */ weakCompareAndSetVolatile(V expectedValue, V newValue)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 */ weakCompareAndSetAcquire(V expectedValue, V newValue)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 */ weakCompareAndSetRelease(V expectedValue, V newValue)436 public final boolean weakCompareAndSetRelease(V expectedValue, V newValue) { 437 return VALUE.weakCompareAndSetRelease(this, expectedValue, newValue); 438 } 439 440 } 441