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 Conversion 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 Conversion 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 Conversion 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 }