Home | History | Annotate | Download | only in atomic
      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/licenses/publicdomain
      5  */
      6 
      7 package java.util.concurrent.atomic;
      8 import sun.misc.Unsafe;
      9 
     10 /**
     11  * An object reference that may be updated atomically. See the {@link
     12  * java.util.concurrent.atomic} package specification for description
     13  * of the properties of atomic variables.
     14  * @since 1.5
     15  * @author Doug Lea
     16  * @param <V> The type of object referred to by this reference
     17  */
     18 public class AtomicReference<V>  implements java.io.Serializable {
     19     private static final long serialVersionUID = -1848883965231344442L;
     20 
     21     private static final Unsafe unsafe = UnsafeAccess.THE_ONE; // android-changed
     22     private static final long valueOffset;
     23 
     24     static {
     25       try {
     26         valueOffset = unsafe.objectFieldOffset
     27             (AtomicReference.class.getDeclaredField("value"));
     28       } catch (Exception ex) { throw new Error(ex); }
     29     }
     30 
     31     private volatile V value;
     32 
     33     /**
     34      * Creates a new AtomicReference with the given initial value.
     35      *
     36      * @param initialValue the initial value
     37      */
     38     public AtomicReference(V initialValue) {
     39         value = initialValue;
     40     }
     41 
     42     /**
     43      * Creates a new AtomicReference with null initial value.
     44      */
     45     public AtomicReference() {
     46     }
     47 
     48     /**
     49      * Gets the current value.
     50      *
     51      * @return the current value
     52      */
     53     public final V get() {
     54         return value;
     55     }
     56 
     57     /**
     58      * Sets to the given value.
     59      *
     60      * @param newValue the new value
     61      */
     62     public final void set(V newValue) {
     63         value = newValue;
     64     }
     65 
     66     /**
     67      * Eventually sets to the given value.
     68      *
     69      * @param newValue the new value
     70      * @since 1.6
     71      */
     72     public final void lazySet(V newValue) {
     73         unsafe.putOrderedObject(this, valueOffset, newValue);
     74     }
     75 
     76     /**
     77      * Atomically sets the value to the given updated value
     78      * if the current value {@code ==} the expected value.
     79      * @param expect the expected value
     80      * @param update the new value
     81      * @return true if successful. False return indicates that
     82      * the actual value was not equal to the expected value.
     83      */
     84     public final boolean compareAndSet(V expect, V update) {
     85         return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
     86     }
     87 
     88     /**
     89      * Atomically sets the value to the given updated value
     90      * if the current value {@code ==} the expected value.
     91      *
     92      * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
     93      * and does not provide ordering guarantees, so is only rarely an
     94      * appropriate alternative to {@code compareAndSet}.
     95      *
     96      * @param expect the expected value
     97      * @param update the new value
     98      * @return true if successful.
     99      */
    100     public final boolean weakCompareAndSet(V expect, V update) {
    101         return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
    102     }
    103 
    104     /**
    105      * Atomically sets to the given value and returns the old value.
    106      *
    107      * @param newValue the new value
    108      * @return the previous value
    109      */
    110     public final V getAndSet(V newValue) {
    111         while (true) {
    112             V x = get();
    113             if (compareAndSet(x, newValue))
    114                 return x;
    115         }
    116     }
    117 
    118     /**
    119      * Returns the String representation of the current value.
    120      * @return the String representation of the current value.
    121      */
    122     public String toString() {
    123         return String.valueOf(get());
    124     }
    125 
    126 }
    127