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      */
AtomicReference(V initialValue)71     public AtomicReference(V initialValue) {
72         value = initialValue;
73     }
74 
75     /**
76      * Creates a new AtomicReference with null initial value.
77      */
AtomicReference()78     public AtomicReference() {
79     }
80 
81     /**
82      * Gets the current value.
83      *
84      * @return the current value
85      */
get()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      */
set(V newValue)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      */
lazySet(V newValue)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      */
compareAndSet(V expect, V update)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      */
weakCompareAndSet(V expect, V update)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")
getAndSet(V newValue)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      */
getAndUpdate(UnaryOperator<V> updateFunction)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      */
updateAndGet(UnaryOperator<V> updateFunction)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      */
getAndAccumulate(V x, BinaryOperator<V> accumulatorFunction)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      */
accumulateAndGet(V x, BinaryOperator<V> accumulatorFunction)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      */
toString()238     public String toString() {
239         return String.valueOf(get());
240     }
241 
242 }
243