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