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.LongBinaryOperator;
39 import java.util.function.LongUnaryOperator;
40 
41 /**
42  * A {@code long} value that may be updated atomically.  See the
43  * {@link java.util.concurrent.atomic} package specification for
44  * description of the properties of atomic variables. An
45  * {@code AtomicLong} is used in applications such as atomically
46  * incremented sequence numbers, and cannot be used as a replacement
47  * for a {@link java.lang.Long}. However, this class does extend
48  * {@code Number} to allow uniform access by tools and utilities that
49  * deal with numerically-based classes.
50  *
51  * @since 1.5
52  * @author Doug Lea
53  */
54 public class AtomicLong extends Number implements java.io.Serializable {
55     private static final long serialVersionUID = 1927816293512124184L;
56 
57     private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
58     private static final long VALUE;
59 
60     /**
61      * Records whether the underlying JVM supports lockless
62      * compareAndSwap for longs. While the Unsafe.compareAndSwapLong
63      * method works in either case, some constructions should be
64      * handled at Java level to avoid locking user-visible locks.
65      */
66     static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8();
67 
68     /**
69      * Returns whether underlying JVM supports lockless CompareAndSet
70      * for longs. Called only once and cached in VM_SUPPORTS_LONG_CAS.
71      */
VMSupportsCS8()72     private static native boolean VMSupportsCS8();
73 
74     static {
75         try {
76             VALUE = U.objectFieldOffset
77                 (AtomicLong.class.getDeclaredField("value"));
78         } catch (ReflectiveOperationException e) {
79             throw new Error(e);
80         }
81     }
82 
83     private volatile long value;
84 
85     /**
86      * Creates a new AtomicLong with the given initial value.
87      *
88      * @param initialValue the initial value
89      */
AtomicLong(long initialValue)90     public AtomicLong(long initialValue) {
91         value = initialValue;
92     }
93 
94     /**
95      * Creates a new AtomicLong with initial value {@code 0}.
96      */
AtomicLong()97     public AtomicLong() {
98     }
99 
100     /**
101      * Gets the current value.
102      *
103      * @return the current value
104      */
get()105     public final long get() {
106         return value;
107     }
108 
109     /**
110      * Sets to the given value.
111      *
112      * @param newValue the new value
113      */
set(long newValue)114     public final void set(long newValue) {
115         // Use putLongVolatile instead of ordinary volatile store when
116         // using compareAndSwapLong, for sake of some 32bit systems.
117         U.putLongVolatile(this, VALUE, newValue);
118     }
119 
120     /**
121      * Eventually sets to the given value.
122      *
123      * @param newValue the new value
124      * @since 1.6
125      */
lazySet(long newValue)126     public final void lazySet(long newValue) {
127         U.putOrderedLong(this, VALUE, newValue);
128     }
129 
130     /**
131      * Atomically sets to the given value and returns the old value.
132      *
133      * @param newValue the new value
134      * @return the previous value
135      */
getAndSet(long newValue)136     public final long getAndSet(long newValue) {
137         return U.getAndSetLong(this, VALUE, newValue);
138     }
139 
140     /**
141      * Atomically sets the value to the given updated value
142      * if the current value {@code ==} the expected value.
143      *
144      * @param expect the expected value
145      * @param update the new value
146      * @return {@code true} if successful. False return indicates that
147      * the actual value was not equal to the expected value.
148      */
compareAndSet(long expect, long update)149     public final boolean compareAndSet(long expect, long update) {
150         return U.compareAndSwapLong(this, VALUE, expect, update);
151     }
152 
153     /**
154      * Atomically sets the value to the given updated value
155      * if the current value {@code ==} the expected value.
156      *
157      * <p><a href="package-summary.html#weakCompareAndSet">May fail
158      * spuriously and does not provide ordering guarantees</a>, so is
159      * only rarely an appropriate alternative to {@code compareAndSet}.
160      *
161      * @param expect the expected value
162      * @param update the new value
163      * @return {@code true} if successful
164      */
weakCompareAndSet(long expect, long update)165     public final boolean weakCompareAndSet(long expect, long update) {
166         return U.compareAndSwapLong(this, VALUE, expect, update);
167     }
168 
169     /**
170      * Atomically increments by one the current value.
171      *
172      * @return the previous value
173      */
getAndIncrement()174     public final long getAndIncrement() {
175         return U.getAndAddLong(this, VALUE, 1L);
176     }
177 
178     /**
179      * Atomically decrements by one the current value.
180      *
181      * @return the previous value
182      */
getAndDecrement()183     public final long getAndDecrement() {
184         return U.getAndAddLong(this, VALUE, -1L);
185     }
186 
187     /**
188      * Atomically adds the given value to the current value.
189      *
190      * @param delta the value to add
191      * @return the previous value
192      */
getAndAdd(long delta)193     public final long getAndAdd(long delta) {
194         return U.getAndAddLong(this, VALUE, delta);
195     }
196 
197     /**
198      * Atomically increments by one the current value.
199      *
200      * @return the updated value
201      */
incrementAndGet()202     public final long incrementAndGet() {
203         return U.getAndAddLong(this, VALUE, 1L) + 1L;
204     }
205 
206     /**
207      * Atomically decrements by one the current value.
208      *
209      * @return the updated value
210      */
decrementAndGet()211     public final long decrementAndGet() {
212         return U.getAndAddLong(this, VALUE, -1L) - 1L;
213     }
214 
215     /**
216      * Atomically adds the given value to the current value.
217      *
218      * @param delta the value to add
219      * @return the updated value
220      */
addAndGet(long delta)221     public final long addAndGet(long delta) {
222         return U.getAndAddLong(this, VALUE, delta) + delta;
223     }
224 
225     /**
226      * Atomically updates the current value with the results of
227      * applying the given function, returning the previous value. The
228      * function should be side-effect-free, since it may be re-applied
229      * when attempted updates fail due to contention among threads.
230      *
231      * @param updateFunction a side-effect-free function
232      * @return the previous value
233      * @since 1.8
234      */
getAndUpdate(LongUnaryOperator updateFunction)235     public final long getAndUpdate(LongUnaryOperator updateFunction) {
236         long prev, next;
237         do {
238             prev = get();
239             next = updateFunction.applyAsLong(prev);
240         } while (!compareAndSet(prev, next));
241         return prev;
242     }
243 
244     /**
245      * Atomically updates the current value with the results of
246      * applying the given function, returning the updated value. The
247      * function should be side-effect-free, since it may be re-applied
248      * when attempted updates fail due to contention among threads.
249      *
250      * @param updateFunction a side-effect-free function
251      * @return the updated value
252      * @since 1.8
253      */
updateAndGet(LongUnaryOperator updateFunction)254     public final long updateAndGet(LongUnaryOperator updateFunction) {
255         long prev, next;
256         do {
257             prev = get();
258             next = updateFunction.applyAsLong(prev);
259         } while (!compareAndSet(prev, next));
260         return next;
261     }
262 
263     /**
264      * Atomically updates the current value with the results of
265      * applying the given function to the current and given values,
266      * returning the previous value. The function should be
267      * side-effect-free, since it may be re-applied when attempted
268      * updates fail due to contention among threads.  The function
269      * is applied with the current value as its first argument,
270      * and the given update as the second argument.
271      *
272      * @param x the update value
273      * @param accumulatorFunction a side-effect-free function of two arguments
274      * @return the previous value
275      * @since 1.8
276      */
getAndAccumulate(long x, LongBinaryOperator accumulatorFunction)277     public final long getAndAccumulate(long x,
278                                        LongBinaryOperator accumulatorFunction) {
279         long prev, next;
280         do {
281             prev = get();
282             next = accumulatorFunction.applyAsLong(prev, x);
283         } while (!compareAndSet(prev, next));
284         return prev;
285     }
286 
287     /**
288      * Atomically updates the current value with the results of
289      * applying the given function to the current and given values,
290      * returning the updated value. The function should be
291      * side-effect-free, since it may be re-applied when attempted
292      * updates fail due to contention among threads.  The function
293      * is applied with the current value as its first argument,
294      * and the given update as the second argument.
295      *
296      * @param x the update value
297      * @param accumulatorFunction a side-effect-free function of two arguments
298      * @return the updated value
299      * @since 1.8
300      */
accumulateAndGet(long x, LongBinaryOperator accumulatorFunction)301     public final long accumulateAndGet(long x,
302                                        LongBinaryOperator accumulatorFunction) {
303         long prev, next;
304         do {
305             prev = get();
306             next = accumulatorFunction.applyAsLong(prev, x);
307         } while (!compareAndSet(prev, next));
308         return next;
309     }
310 
311     /**
312      * Returns the String representation of the current value.
313      * @return the String representation of the current value
314      */
toString()315     public String toString() {
316         return Long.toString(get());
317     }
318 
319     /**
320      * Returns the value of this {@code AtomicLong} as an {@code int}
321      * after a narrowing primitive conversion.
322      * @jls 5.1.3 Narrowing Primitive Conversions
323      */
intValue()324     public int intValue() {
325         return (int)get();
326     }
327 
328     /**
329      * Returns the value of this {@code AtomicLong} as a {@code long}.
330      * Equivalent to {@link #get()}.
331      */
longValue()332     public long longValue() {
333         return get();
334     }
335 
336     /**
337      * Returns the value of this {@code AtomicLong} as a {@code float}
338      * after a widening primitive conversion.
339      * @jls 5.1.2 Widening Primitive Conversions
340      */
floatValue()341     public float floatValue() {
342         return (float)get();
343     }
344 
345     /**
346      * Returns the value of this {@code AtomicLong} as a {@code double}
347      * after a widening primitive conversion.
348      * @jls 5.1.2 Widening Primitive Conversions
349      */
doubleValue()350     public double doubleValue() {
351         return (double)get();
352     }
353 
354 }
355