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 Error(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 }