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