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