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
36package java.util.concurrent.atomic;
37
38import java.util.function.LongBinaryOperator;
39import 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 */
54public 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     */
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     */
90    public AtomicLong(long initialValue) {
91        value = initialValue;
92    }
93
94    /**
95     * Creates a new AtomicLong with initial value {@code 0}.
96     */
97    public AtomicLong() {
98    }
99
100    /**
101     * Gets the current value.
102     *
103     * @return the current value
104     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
350    public double doubleValue() {
351        return (double)get();
352    }
353
354}
355