Home | History | Annotate | Download | only in atomic
      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.util.function.BinaryOperator;
     39 import java.util.function.UnaryOperator;
     40 
     41 /**
     42  * An object reference that may be updated atomically. See the {@link
     43  * java.util.concurrent.atomic} package specification for description
     44  * of the properties of atomic variables.
     45  * @since 1.5
     46  * @author Doug Lea
     47  * @param <V> The type of object referred to by this reference
     48  */
     49 public class AtomicReference<V> implements java.io.Serializable {
     50     private static final long serialVersionUID = -1848883965231344442L;
     51 
     52     private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
     53     private static final long VALUE;
     54 
     55     static {
     56         try {
     57             VALUE = U.objectFieldOffset
     58                 (AtomicReference.class.getDeclaredField("value"));
     59         } catch (ReflectiveOperationException e) {
     60             throw new Error(e);
     61         }
     62     }
     63 
     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      */
     71     public AtomicReference(V initialValue) {
     72         value = initialValue;
     73     }
     74 
     75     /**
     76      * Creates a new AtomicReference with null initial value.
     77      */
     78     public AtomicReference() {
     79     }
     80 
     81     /**
     82      * Gets the current value.
     83      *
     84      * @return the current value
     85      */
     86     public final V get() {
     87         return value;
     88     }
     89 
     90     /**
     91      * Sets to the given value.
     92      *
     93      * @param newValue the new value
     94      */
     95     public final void set(V newValue) {
     96         value = newValue;
     97     }
     98 
     99     /**
    100      * Eventually sets to the given value.
    101      *
    102      * @param newValue the new value
    103      * @since 1.6
    104      */
    105     public final void lazySet(V newValue) {
    106         U.putOrderedObject(this, VALUE, newValue);
    107     }
    108 
    109     /**
    110      * Atomically sets the value to the given updated value
    111      * if the current value {@code ==} the expected value.
    112      * @param expect the expected value
    113      * @param update the new value
    114      * @return {@code true} if successful. False return indicates that
    115      * the actual value was not equal to the expected value.
    116      */
    117     public final boolean compareAndSet(V expect, V update) {
    118         return U.compareAndSwapObject(this, VALUE, expect, update);
    119     }
    120 
    121     /**
    122      * Atomically sets the value to the given updated value
    123      * if the current value {@code ==} the expected value.
    124      *
    125      * <p><a href="package-summary.html#weakCompareAndSet">May fail
    126      * spuriously and does not provide ordering guarantees</a>, so is
    127      * only rarely an appropriate alternative to {@code compareAndSet}.
    128      *
    129      * @param expect the expected value
    130      * @param update the new value
    131      * @return {@code true} if successful
    132      */
    133     public final boolean weakCompareAndSet(V expect, V update) {
    134         return U.compareAndSwapObject(this, VALUE, expect, update);
    135     }
    136 
    137     /**
    138      * Atomically sets to the given value and returns the old value.
    139      *
    140      * @param newValue the new value
    141      * @return the previous value
    142      */
    143     @SuppressWarnings("unchecked")
    144     public final V getAndSet(V newValue) {
    145         return (V)U.getAndSetObject(this, VALUE, newValue);
    146     }
    147 
    148     /**
    149      * Atomically updates the current value with the results of
    150      * applying the given function, returning the previous value. The
    151      * function should be side-effect-free, since it may be re-applied
    152      * when attempted updates fail due to contention among threads.
    153      *
    154      * @param updateFunction a side-effect-free function
    155      * @return the previous value
    156      * @since 1.8
    157      */
    158     public final V getAndUpdate(UnaryOperator<V> updateFunction) {
    159         V prev, next;
    160         do {
    161             prev = get();
    162             next = updateFunction.apply(prev);
    163         } while (!compareAndSet(prev, next));
    164         return prev;
    165     }
    166 
    167     /**
    168      * Atomically updates 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, next;
    179         do {
    180             prev = get();
    181             next = updateFunction.apply(prev);
    182         } while (!compareAndSet(prev, next));
    183         return next;
    184     }
    185 
    186     /**
    187      * Atomically updates the current value with the results of
    188      * applying the given function to the current and given values,
    189      * returning the previous value. The function should be
    190      * side-effect-free, since it may be re-applied when attempted
    191      * updates fail due to contention among threads.  The function
    192      * is applied with the current value as its first argument,
    193      * and the given update as the second argument.
    194      *
    195      * @param x the update value
    196      * @param accumulatorFunction a side-effect-free function of two arguments
    197      * @return the previous value
    198      * @since 1.8
    199      */
    200     public final V getAndAccumulate(V x,
    201                                     BinaryOperator<V> accumulatorFunction) {
    202         V prev, next;
    203         do {
    204             prev = get();
    205             next = accumulatorFunction.apply(prev, x);
    206         } while (!compareAndSet(prev, next));
    207         return prev;
    208     }
    209 
    210     /**
    211      * Atomically updates the current value with the results of
    212      * applying the given function to the current and given values,
    213      * returning the updated value. The function should be
    214      * side-effect-free, since it may be re-applied when attempted
    215      * updates fail due to contention among threads.  The function
    216      * is applied with the current value as its first argument,
    217      * and the given update as the second argument.
    218      *
    219      * @param x the update value
    220      * @param accumulatorFunction a side-effect-free function of two arguments
    221      * @return the updated value
    222      * @since 1.8
    223      */
    224     public final V accumulateAndGet(V x,
    225                                     BinaryOperator<V> accumulatorFunction) {
    226         V prev, next;
    227         do {
    228             prev = get();
    229             next = accumulatorFunction.apply(prev, x);
    230         } while (!compareAndSet(prev, next));
    231         return next;
    232     }
    233 
    234     /**
    235      * Returns the String representation of the current value.
    236      * @return the String representation of the current value
    237      */
    238     public String toString() {
    239         return String.valueOf(get());
    240     }
    241 
    242 }
    243