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.lang.invoke.VarHandle;
39 import java.util.function.IntBinaryOperator;
40 import java.util.function.IntUnaryOperator;
41
42 /**
43 * An {@code int} value that may be updated atomically. See the
44 * {@link VarHandle} specification for descriptions of the properties
45 * of atomic accesses. An {@code AtomicInteger} is used in
46 * applications such as atomically incremented counters, and cannot be
47 * used as a replacement for an {@link java.lang.Integer}. However,
48 * this class does extend {@code Number} to allow uniform access by
49 * tools and utilities that 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 /*
58 * This class intended to be implemented using VarHandles, but there
59 * are unresolved cyclic startup dependencies.
60 */
61 private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
62 private static final long VALUE = U.objectFieldOffset(AtomicInteger.class, "value");
63
64 private volatile int value;
65
66 /**
67 * Creates a new AtomicInteger with the given initial value.
68 *
69 * @param initialValue the initial value
70 */
71 public AtomicInteger(int initialValue) {
72 value = initialValue;
73 }
74
75 /**
76 * Creates a new AtomicInteger with initial value {@code 0}.
77 */
78 public AtomicInteger() {
79 }
80
81 /**
82 * Returns the current value,
83 * with memory effects as specified by {@link VarHandle#getVolatile}.
84 *
85 * @return the current value
86 */
87 public final int get() {
88 return value;
89 }
90
91 /**
92 * Sets the value to {@code newValue},
93 * with memory effects as specified by {@link VarHandle#setVolatile}.
94 *
95 * @param newValue the new value
96 */
97 public final void set(int newValue) {
98 value = newValue;
99 }
100
101 /**
102 * Sets the value to {@code newValue},
103 * with memory effects as specified by {@link VarHandle#setRelease}.
104 *
105 * @param newValue the new value
106 * @since 1.6
107 */
108 public final void lazySet(int newValue) {
109 U.putIntRelease(this, VALUE, newValue);
110 }
111
112 /**
113 * Atomically sets the value to {@code newValue} and returns the old value,
114 * with memory effects as specified by {@link VarHandle#getAndSet}.
115 *
116 * @param newValue the new value
117 * @return the previous value
118 */
119 public final int getAndSet(int newValue) {
120 return U.getAndSetInt(this, VALUE, newValue);
121 }
122
123 /**
124 * Atomically sets the value to {@code newValue}
125 * if the current value {@code == expectedValue},
126 * with memory effects as specified by {@link VarHandle#compareAndSet}.
127 *
128 * @param expectedValue the expected value
129 * @param newValue 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 expectedValue, int newValue) {
134 return U.compareAndSetInt(this, VALUE, expectedValue, newValue);
135 }
136
137 /**
138 * Possibly atomically sets the value to {@code newValue}
139 * if the current value {@code == expectedValue},
140 * with memory effects as specified by {@link VarHandle#weakCompareAndSetPlain}.
141 *
142 * @deprecated This method has plain memory effects but the method
143 * name implies volatile memory effects (see methods such as
144 * {@link #compareAndExchange} and {@link #compareAndSet}). To avoid
145 * confusion over plain or volatile memory effects it is recommended that
146 * the method {@link #weakCompareAndSetPlain} be used instead.
147 *
148 * @param expectedValue the expected value
149 * @param newValue the new value
150 * @return {@code true} if successful
151 * @see #weakCompareAndSetPlain
152 */
153 @Deprecated(since="9")
154 public final boolean weakCompareAndSet(int expectedValue, int newValue) {
155 return U.weakCompareAndSetIntPlain(this, VALUE, expectedValue, newValue);
156 }
157
158 /**
159 * Possibly atomically sets the value to {@code newValue}
160 * if the current value {@code == expectedValue},
161 * with memory effects as specified by {@link VarHandle#weakCompareAndSetPlain}.
162 *
163 * @param expectedValue the expected value
164 * @param newValue the new value
165 * @return {@code true} if successful
166 * @since 9
167 */
168 public final boolean weakCompareAndSetPlain(int expectedValue, int newValue) {
169 return U.weakCompareAndSetIntPlain(this, VALUE, expectedValue, newValue);
170 }
171
172 /**
173 * Atomically increments the current value,
174 * with memory effects as specified by {@link VarHandle#getAndAdd}.
175 *
176 * <p>Equivalent to {@code getAndAdd(1)}.
177 *
178 * @return the previous value
179 */
180 public final int getAndIncrement() {
181 return U.getAndAddInt(this, VALUE, 1);
182 }
183
184 /**
185 * Atomically decrements the current value,
186 * with memory effects as specified by {@link VarHandle#getAndAdd}.
187 *
188 * <p>Equivalent to {@code getAndAdd(-1)}.
189 *
190 * @return the previous value
191 */
192 public final int getAndDecrement() {
193 return U.getAndAddInt(this, VALUE, -1);
194 }
195
196 /**
197 * Atomically adds the given value to the current value,
198 * with memory effects as specified by {@link VarHandle#getAndAdd}.
199 *
200 * @param delta the value to add
201 * @return the previous value
202 */
203 public final int getAndAdd(int delta) {
204 return U.getAndAddInt(this, VALUE, delta);
205 }
206
207 /**
208 * Atomically increments the current value,
209 * with memory effects as specified by {@link VarHandle#getAndAdd}.
210 *
211 * <p>Equivalent to {@code addAndGet(1)}.
212 *
213 * @return the updated value
214 */
215 public final int incrementAndGet() {
216 return U.getAndAddInt(this, VALUE, 1) + 1;
217 }
218
219 /**
220 * Atomically decrements the current value,
221 * with memory effects as specified by {@link VarHandle#getAndAdd}.
222 *
223 * <p>Equivalent to {@code addAndGet(-1)}.
224 *
225 * @return the updated value
226 */
227 public final int decrementAndGet() {
228 return U.getAndAddInt(this, VALUE, -1) - 1;
229 }
230
231 /**
232 * Atomically adds the given value to the current value,
233 * with memory effects as specified by {@link VarHandle#getAndAdd}.
234 *
235 * @param delta the value to add
236 * @return the updated value
237 */
238 public final int addAndGet(int delta) {
239 return U.getAndAddInt(this, VALUE, delta) + delta;
240 }
241
242 /**
243 * Atomically updates (with memory effects as specified by {@link
244 * VarHandle#compareAndSet}) the current value with the results of
245 * applying the given function, returning the previous value. The
246 * function should be side-effect-free, since it may be re-applied
247 * when attempted updates fail due to contention among threads.
248 *
249 * @param updateFunction a side-effect-free function
250 * @return the previous value
251 * @since 1.8
252 */
253 public final int getAndUpdate(IntUnaryOperator updateFunction) {
254 int prev = get(), next = 0;
255 for (boolean haveNext = false;;) {
256 if (!haveNext)
257 next = updateFunction.applyAsInt(prev);
258 if (weakCompareAndSetVolatile(prev, next))
259 return prev;
260 haveNext = (prev == (prev = get()));
261 }
262 }
263
264 /**
265 * Atomically updates (with memory effects as specified by {@link
266 * VarHandle#compareAndSet}) the current value with the results of
267 * applying the given function, returning the updated value. The
268 * function should be side-effect-free, since it may be re-applied
269 * when attempted updates fail due to contention among threads.
270 *
271 * @param updateFunction a side-effect-free function
272 * @return the updated value
273 * @since 1.8
274 */
275 public final int updateAndGet(IntUnaryOperator updateFunction) {
276 int prev = get(), next = 0;
277 for (boolean haveNext = false;;) {
278 if (!haveNext)
279 next = updateFunction.applyAsInt(prev);
280 if (weakCompareAndSetVolatile(prev, next))
281 return next;
282 haveNext = (prev == (prev = get()));
283 }
284 }
285
286 /**
287 * Atomically updates (with memory effects as specified by {@link
288 * VarHandle#compareAndSet}) the current value with the results of
289 * applying the given function to the current and given values,
290 * returning the previous 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 is
293 * applied with the current value as its first argument, and the
294 * 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 previous value
299 * @since 1.8
300 */
301 public final int getAndAccumulate(int x,
302 IntBinaryOperator accumulatorFunction) {
303 int prev = get(), next = 0;
304 for (boolean haveNext = false;;) {
305 if (!haveNext)
306 next = accumulatorFunction.applyAsInt(prev, x);
307 if (weakCompareAndSetVolatile(prev, next))
308 return prev;
309 haveNext = (prev == (prev = get()));
310 }
311 }
312
313 /**
314 * Atomically updates (with memory effects as specified by {@link
315 * VarHandle#compareAndSet}) the current value with the results of
316 * applying the given function to the current and given values,
317 * returning the updated value. The function should be
318 * side-effect-free, since it may be re-applied when attempted
319 * updates fail due to contention among threads. The function is
320 * applied with the current value as its first argument, and the
321 * given update as the second argument.
322 *
323 * @param x the update value
324 * @param accumulatorFunction a side-effect-free function of two arguments
325 * @return the updated value
326 * @since 1.8
327 */
328 public final int accumulateAndGet(int x,
329 IntBinaryOperator accumulatorFunction) {
330 int prev = get(), next = 0;
331 for (boolean haveNext = false;;) {
332 if (!haveNext)
333 next = accumulatorFunction.applyAsInt(prev, x);
334 if (weakCompareAndSetVolatile(prev, next))
335 return next;
336 haveNext = (prev == (prev = get()));
337 }
338 }
339
340 /**
341 * Returns the String representation of the current value.
342 * @return the String representation of the current value
343 */
344 public String toString() {
345 return Integer.toString(get());
346 }
347
348 /**
349 * Returns the current value of this {@code AtomicInteger} as an
350 * {@code int},
351 * with memory effects as specified by {@link VarHandle#getVolatile}.
352 *
353 * Equivalent to {@link #get()}.
354 */
355 public int intValue() {
356 return get();
357 }
358
359 /**
360 * Returns the current value of this {@code AtomicInteger} as a
361 * {@code long} after a widening primitive conversion,
362 * with memory effects as specified by {@link VarHandle#getVolatile}.
363 * @jls 5.1.2 Widening Primitive Conversions
364 */
365 public long longValue() {
366 return (long)get();
367 }
368
369 /**
370 * Returns the current value of this {@code AtomicInteger} as a
371 * {@code float} after a widening primitive conversion,
372 * with memory effects as specified by {@link VarHandle#getVolatile}.
373 * @jls 5.1.2 Widening Primitive Conversions
374 */
375 public float floatValue() {
376 return (float)get();
377 }
378
379 /**
380 * Returns the current value of this {@code AtomicInteger} as a
381 * {@code double} after a widening primitive conversion,
382 * with memory effects as specified by {@link VarHandle#getVolatile}.
383 * @jls 5.1.2 Widening Primitive Conversions
384 */
385 public double doubleValue() {
386 return (double)get();
387 }
388
389 // jdk9
390
391 /**
392 * Returns the current value, with memory semantics of reading as
393 * if the variable was declared non-{@code volatile}.
394 *
395 * @return the value
396 * @since 9
397 */
398 public final int getPlain() {
399 return U.getInt(this, VALUE);
400 }
401
402 /**
403 * Sets the value to {@code newValue}, with memory semantics
404 * of setting as if the variable was declared non-{@code volatile}
405 * and non-{@code final}.
406 *
407 * @param newValue the new value
408 * @since 9
409 */
410 public final void setPlain(int newValue) {
411 U.putInt(this, VALUE, newValue);
412 }
413
414 /**
415 * Returns the current value,
416 * with memory effects as specified by {@link VarHandle#getOpaque}.
417 *
418 * @return the value
419 * @since 9
420 */
421 public final int getOpaque() {
422 return U.getIntOpaque(this, VALUE);
423 }
424
425 /**
426 * Sets the value to {@code newValue},
427 * with memory effects as specified by {@link VarHandle#setOpaque}.
428 *
429 * @param newValue the new value
430 * @since 9
431 */
432 public final void setOpaque(int newValue) {
433 U.putIntOpaque(this, VALUE, newValue);
434 }
435
436 /**
437 * Returns the current value,
438 * with memory effects as specified by {@link VarHandle#getAcquire}.
439 *
440 * @return the value
441 * @since 9
442 */
443 public final int getAcquire() {
444 return U.getIntAcquire(this, VALUE);
445 }
446
447 /**
448 * Sets the value to {@code newValue},
449 * with memory effects as specified by {@link VarHandle#setRelease}.
450 *
451 * @param newValue the new value
452 * @since 9
453 */
454 public final void setRelease(int newValue) {
455 U.putIntRelease(this, VALUE, newValue);
456 }
457
458 /**
459 * Atomically sets the value to {@code newValue} if the current value,
460 * referred to as the <em>witness value</em>, {@code == expectedValue},
461 * with memory effects as specified by
462 * {@link VarHandle#compareAndExchange}.
463 *
464 * @param expectedValue the expected value
465 * @param newValue the new value
466 * @return the witness value, which will be the same as the
467 * expected value if successful
468 * @since 9
469 */
470 public final int compareAndExchange(int expectedValue, int newValue) {
471 return U.compareAndExchangeInt(this, VALUE, expectedValue, newValue);
472 }
473
474 /**
475 * Atomically sets the value to {@code newValue} if the current value,
476 * referred to as the <em>witness value</em>, {@code == expectedValue},
477 * with memory effects as specified by
478 * {@link VarHandle#compareAndExchangeAcquire}.
479 *
480 * @param expectedValue the expected value
481 * @param newValue the new value
482 * @return the witness value, which will be the same as the
483 * expected value if successful
484 * @since 9
485 */
486 public final int compareAndExchangeAcquire(int expectedValue, int newValue) {
487 return U.compareAndExchangeIntAcquire(this, VALUE, expectedValue, newValue);
488 }
489
490 /**
491 * Atomically sets the value to {@code newValue} if the current value,
492 * referred to as the <em>witness value</em>, {@code == expectedValue},
493 * with memory effects as specified by
494 * {@link VarHandle#compareAndExchangeRelease}.
495 *
496 * @param expectedValue the expected value
497 * @param newValue the new value
498 * @return the witness value, which will be the same as the
499 * expected value if successful
500 * @since 9
501 */
502 public final int compareAndExchangeRelease(int expectedValue, int newValue) {
503 return U.compareAndExchangeIntRelease(this, VALUE, expectedValue, newValue);
504 }
505
506 /**
507 * Possibly atomically sets the value to {@code newValue} if
508 * the current value {@code == expectedValue},
509 * with memory effects as specified by
510 * {@link VarHandle#weakCompareAndSet}.
511 *
512 * @param expectedValue the expected value
513 * @param newValue the new value
514 * @return {@code true} if successful
515 * @since 9
516 */
517 public final boolean weakCompareAndSetVolatile(int expectedValue, int newValue) {
518 return U.weakCompareAndSetInt(this, VALUE, expectedValue, newValue);
519 }
520
521 /**
522 * Possibly atomically sets the value to {@code newValue} if
523 * the current value {@code == expectedValue},
524 * with memory effects as specified by
525 * {@link VarHandle#weakCompareAndSetAcquire}.
526 *
527 * @param expectedValue the expected value
528 * @param newValue the new value
529 * @return {@code true} if successful
530 * @since 9
531 */
532 public final boolean weakCompareAndSetAcquire(int expectedValue, int newValue) {
533 return U.weakCompareAndSetIntAcquire(this, VALUE, expectedValue, newValue);
534 }
535
536 /**
537 * Possibly atomically sets the value to {@code newValue} if
538 * the current value {@code == expectedValue},
539 * with memory effects as specified by
540 * {@link VarHandle#weakCompareAndSetRelease}.
541 *
542 * @param expectedValue the expected value
543 * @param newValue the new value
544 * @return {@code true} if successful
545 * @since 9
546 */
547 public final boolean weakCompareAndSetRelease(int expectedValue, int newValue) {
548 return U.weakCompareAndSetIntRelease(this, VALUE, expectedValue, newValue);
549 }
550
551 }
552