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/publicdomain/zero/1.0/
5 */
6
7package java.util.concurrent.atomic;
8import 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 */
18public class AtomicReference<V> implements java.io.Serializable {
19    private static final long serialVersionUID = -1848883965231344442L;
20
21    private static final Unsafe unsafe = Unsafe.getUnsafe();
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><a href="package-summary.html#weakCompareAndSet">May fail
93     * spuriously and does not provide ordering guarantees</a>, so is
94     * only rarely an 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