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.IntBinaryOperator;
39 import 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  */
54 public 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      */
AtomicInteger(int initialValue)76     public AtomicInteger(int initialValue) {
77         value = initialValue;
78     }
79 
80     /**
81      * Creates a new AtomicInteger with initial value {@code 0}.
82      */
AtomicInteger()83     public AtomicInteger() {
84     }
85 
86     /**
87      * Gets the current value.
88      *
89      * @return the current value
90      */
get()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      */
set(int newValue)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      */
lazySet(int newValue)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      */
getAndSet(int newValue)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      */
compareAndSet(int expect, int update)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      */
weakCompareAndSet(int expect, int update)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      */
getAndIncrement()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      */
getAndDecrement()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      */
getAndAdd(int delta)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      */
incrementAndGet()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      */
decrementAndGet()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      */
addAndGet(int delta)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      */
getAndUpdate(IntUnaryOperator updateFunction)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      */
updateAndGet(IntUnaryOperator updateFunction)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      */
getAndAccumulate(int x, IntBinaryOperator accumulatorFunction)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      */
accumulateAndGet(int x, IntBinaryOperator accumulatorFunction)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      */
toString()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      */
intValue()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      */
longValue()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      */
floatValue()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      */
doubleValue()334     public double doubleValue() {
335         return (double)get();
336     }
337 
338 }
339