AtomicReference.java revision a807b4d808d2591894daf13aab179b2e9c46a2f5
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Written by Doug Lea with assistance from members of JCP JSR-166
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Expert Group and released to the public domain, as explained at
4a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * http://creativecommons.org/publicdomain/zero/1.0/
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util.concurrent.atomic;
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport sun.misc.Unsafe;
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * An object reference that may be updated atomically. See the {@link
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * java.util.concurrent.atomic} package specification for description
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of the properties of atomic variables.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @since 1.5
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @author Doug Lea
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param <V> The type of object referred to by this reference
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
18bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilsonpublic class AtomicReference<V>  implements java.io.Serializable {
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final long serialVersionUID = -1848883965231344442L;
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
21a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson    private static final Unsafe unsafe = Unsafe.getUnsafe();
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final long valueOffset;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static {
25a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson        try {
26a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            valueOffset = unsafe.objectFieldOffset
27a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson                (AtomicReference.class.getDeclaredField("value"));
28a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson        } catch (Exception ex) { throw new Error(ex); }
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private volatile V value;
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
34bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Creates a new AtomicReference with the given initial value.
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param initialValue the initial value
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public AtomicReference(V initialValue) {
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        value = initialValue;
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
43bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Creates a new AtomicReference with null initial value.
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public AtomicReference() {
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
47bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
49bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Gets the current value.
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the current value
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final V get() {
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return value;
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
56bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
58bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Sets to the given value.
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param newValue the new value
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final void set(V newValue) {
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        value = newValue;
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
65bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Eventually sets to the given value.
686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param newValue the new value
706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @since 1.6
716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    public final void lazySet(V newValue) {
736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        unsafe.putOrderedObject(this, valueOffset, newValue);
746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
77bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically sets the value to the given updated value
78bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * if the current value {@code ==} the expected value.
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param expect the expected value
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param update the new value
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return true if successful. False return indicates that
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the actual value was not equal to the expected value.
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final boolean compareAndSet(V expect, V update) {
85bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
89bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically sets the value to the given updated value
90bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * if the current value {@code ==} the expected value.
91bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
92bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
93bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * and does not provide ordering guarantees, so is only rarely an
94bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * appropriate alternative to {@code compareAndSet}.
95bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param expect the expected value
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param update the new value
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return true if successful.
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final boolean weakCompareAndSet(V expect, V update) {
101bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
105bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically sets to the given value and returns the old value.
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param newValue the new value
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the previous value
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final V getAndSet(V newValue) {
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (true) {
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            V x = get();
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (compareAndSet(x, newValue))
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return x;
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the String representation of the current value.
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the String representation of the current value.
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toString() {
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return String.valueOf(get());
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
127