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