1 /*
2  * Written by Doug Lea with assistance from members of JCP JSR-166
3  * Expert Group and released to the public domain, as explained at
4  * http://creativecommons.org/publicdomain/zero/1.0/
5  */
6 
7 package java.util.concurrent.atomic;
8 
9 import java.util.function.IntBinaryOperator;
10 import java.util.function.IntUnaryOperator;
11 
12 /**
13  * An {@code int} value that may be updated atomically.  See the
14  * {@link java.util.concurrent.atomic} package specification for
15  * description of the properties of atomic variables. An
16  * {@code AtomicInteger} is used in applications such as atomically
17  * incremented counters, and cannot be used as a replacement for an
18  * {@link java.lang.Integer}. However, this class does extend
19  * {@code Number} to allow uniform access by tools and utilities that
20  * deal with numerically-based classes.
21  *
22  * @since 1.5
23  * @author Doug Lea
24  */
25 public class AtomicInteger extends Number implements java.io.Serializable {
26     private static final long serialVersionUID = 6214790243416807050L;
27 
28     private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
29     private static final long VALUE;
30 
31     static {
32         try {
33             VALUE = U.objectFieldOffset
34                 (AtomicInteger.class.getDeclaredField("value"));
35         } catch (ReflectiveOperationException e) {
36             throw new Error(e);
37         }
38     }
39 
40     private volatile int value;
41 
42     /**
43      * Creates a new AtomicInteger with the given initial value.
44      *
45      * @param initialValue the initial value
46      */
AtomicInteger(int initialValue)47     public AtomicInteger(int initialValue) {
48         value = initialValue;
49     }
50 
51     /**
52      * Creates a new AtomicInteger with initial value {@code 0}.
53      */
AtomicInteger()54     public AtomicInteger() {
55     }
56 
57     /**
58      * Gets the current value.
59      *
60      * @return the current value
61      */
get()62     public final int get() {
63         return value;
64     }
65 
66     /**
67      * Sets to the given value.
68      *
69      * @param newValue the new value
70      */
set(int newValue)71     public final void set(int newValue) {
72         value = newValue;
73     }
74 
75     /**
76      * Eventually sets to the given value.
77      *
78      * @param newValue the new value
79      * @since 1.6
80      */
lazySet(int newValue)81     public final void lazySet(int newValue) {
82         U.putOrderedInt(this, VALUE, newValue);
83     }
84 
85     /**
86      * Atomically sets to the given value and returns the old value.
87      *
88      * @param newValue the new value
89      * @return the previous value
90      */
getAndSet(int newValue)91     public final int getAndSet(int newValue) {
92         return U.getAndSetInt(this, VALUE, newValue);
93     }
94 
95     /**
96      * Atomically sets the value to the given updated value
97      * if the current value {@code ==} the expected value.
98      *
99      * @param expect the expected value
100      * @param update the new value
101      * @return {@code true} if successful. False return indicates that
102      * the actual value was not equal to the expected value.
103      */
compareAndSet(int expect, int update)104     public final boolean compareAndSet(int expect, int update) {
105         return U.compareAndSwapInt(this, VALUE, expect, update);
106     }
107 
108     /**
109      * Atomically sets the value to the given updated value
110      * if the current value {@code ==} the expected value.
111      *
112      * <p><a href="package-summary.html#weakCompareAndSet">May fail
113      * spuriously and does not provide ordering guarantees</a>, so is
114      * only rarely an appropriate alternative to {@code compareAndSet}.
115      *
116      * @param expect the expected value
117      * @param update the new value
118      * @return {@code true} if successful
119      */
weakCompareAndSet(int expect, int update)120     public final boolean weakCompareAndSet(int expect, int update) {
121         return U.compareAndSwapInt(this, VALUE, expect, update);
122     }
123 
124     /**
125      * Atomically increments by one the current value.
126      *
127      * @return the previous value
128      */
getAndIncrement()129     public final int getAndIncrement() {
130         return U.getAndAddInt(this, VALUE, 1);
131     }
132 
133     /**
134      * Atomically decrements by one the current value.
135      *
136      * @return the previous value
137      */
getAndDecrement()138     public final int getAndDecrement() {
139         return U.getAndAddInt(this, VALUE, -1);
140     }
141 
142     /**
143      * Atomically adds the given value to the current value.
144      *
145      * @param delta the value to add
146      * @return the previous value
147      */
getAndAdd(int delta)148     public final int getAndAdd(int delta) {
149         return U.getAndAddInt(this, VALUE, delta);
150     }
151 
152     /**
153      * Atomically increments by one the current value.
154      *
155      * @return the updated value
156      */
incrementAndGet()157     public final int incrementAndGet() {
158         return U.getAndAddInt(this, VALUE, 1) + 1;
159     }
160 
161     /**
162      * Atomically decrements by one the current value.
163      *
164      * @return the updated value
165      */
decrementAndGet()166     public final int decrementAndGet() {
167         return U.getAndAddInt(this, VALUE, -1) - 1;
168     }
169 
170     /**
171      * Atomically adds the given value to the current value.
172      *
173      * @param delta the value to add
174      * @return the updated value
175      */
addAndGet(int delta)176     public final int addAndGet(int delta) {
177         return U.getAndAddInt(this, VALUE, delta) + delta;
178     }
179 
180     /**
181      * Atomically updates the current value with the results of
182      * applying the given function, returning the previous value. The
183      * function should be side-effect-free, since it may be re-applied
184      * when attempted updates fail due to contention among threads.
185      *
186      * @param updateFunction a side-effect-free function
187      * @return the previous value
188      * @since 1.8
189      */
getAndUpdate(IntUnaryOperator updateFunction)190     public final int getAndUpdate(IntUnaryOperator updateFunction) {
191         int prev, next;
192         do {
193             prev = get();
194             next = updateFunction.applyAsInt(prev);
195         } while (!compareAndSet(prev, next));
196         return prev;
197     }
198 
199     /**
200      * Atomically updates the current value with the results of
201      * applying the given function, returning the updated value. The
202      * function should be side-effect-free, since it may be re-applied
203      * when attempted updates fail due to contention among threads.
204      *
205      * @param updateFunction a side-effect-free function
206      * @return the updated value
207      * @since 1.8
208      */
updateAndGet(IntUnaryOperator updateFunction)209     public final int updateAndGet(IntUnaryOperator updateFunction) {
210         int prev, next;
211         do {
212             prev = get();
213             next = updateFunction.applyAsInt(prev);
214         } while (!compareAndSet(prev, next));
215         return next;
216     }
217 
218     /**
219      * Atomically updates the current value with the results of
220      * applying the given function to the current and given values,
221      * returning the previous value. The function should be
222      * side-effect-free, since it may be re-applied when attempted
223      * updates fail due to contention among threads.  The function
224      * is applied with the current value as its first argument,
225      * and the given update as the second argument.
226      *
227      * @param x the update value
228      * @param accumulatorFunction a side-effect-free function of two arguments
229      * @return the previous value
230      * @since 1.8
231      */
getAndAccumulate(int x, IntBinaryOperator accumulatorFunction)232     public final int getAndAccumulate(int x,
233                                       IntBinaryOperator accumulatorFunction) {
234         int prev, next;
235         do {
236             prev = get();
237             next = accumulatorFunction.applyAsInt(prev, x);
238         } while (!compareAndSet(prev, next));
239         return prev;
240     }
241 
242     /**
243      * Atomically updates the current value with the results of
244      * applying the given function to the current and given values,
245      * returning the updated value. The function should be
246      * side-effect-free, since it may be re-applied when attempted
247      * updates fail due to contention among threads.  The function
248      * is applied with the current value as its first argument,
249      * and the given update as the second argument.
250      *
251      * @param x the update value
252      * @param accumulatorFunction a side-effect-free function of two arguments
253      * @return the updated value
254      * @since 1.8
255      */
accumulateAndGet(int x, IntBinaryOperator accumulatorFunction)256     public final int accumulateAndGet(int x,
257                                       IntBinaryOperator accumulatorFunction) {
258         int prev, next;
259         do {
260             prev = get();
261             next = accumulatorFunction.applyAsInt(prev, x);
262         } while (!compareAndSet(prev, next));
263         return next;
264     }
265 
266     /**
267      * Returns the String representation of the current value.
268      * @return the String representation of the current value
269      */
toString()270     public String toString() {
271         return Integer.toString(get());
272     }
273 
274     /**
275      * Returns the value of this {@code AtomicInteger} as an {@code int}.
276      * Equivalent to {@link #get()}.
277      */
intValue()278     public int intValue() {
279         return get();
280     }
281 
282     /**
283      * Returns the value of this {@code AtomicInteger} as a {@code long}
284      * after a widening primitive conversion.
285      * @jls 5.1.2 Widening Primitive Conversions
286      */
longValue()287     public long longValue() {
288         return (long)get();
289     }
290 
291     /**
292      * Returns the value of this {@code AtomicInteger} as a {@code float}
293      * after a widening primitive conversion.
294      * @jls 5.1.2 Widening Primitive Conversions
295      */
floatValue()296     public float floatValue() {
297         return (float)get();
298     }
299 
300     /**
301      * Returns the value of this {@code AtomicInteger} as a {@code double}
302      * after a widening primitive conversion.
303      * @jls 5.1.2 Widening Primitive Conversions
304      */
doubleValue()305     public double doubleValue() {
306         return (double)get();
307     }
308 
309 }
310