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 import java.util.functions.IntUnaryOperator; 38 import sun.misc.Unsafe; 39 40 /** 41 * An {@code int} value that may be updated atomically. See the 42 * {@link java.util.concurrent.atomic} package specification for 43 * description of the properties of atomic variables. An 44 * {@code AtomicInteger} is used in applications such as atomically 45 * incremented counters, and cannot be used as a replacement for an 46 * {@link java.lang.Integer}. However, this class does extend 47 * {@code Number} to allow uniform access by tools and utilities that 48 * deal with numerically-based classes. 49 * 50 * @since 1.5 51 * @author Doug Lea 52 */ 53 public class AtomicInteger extends Number implements java.io.Serializable { 54 private static final long serialVersionUID = 6214790243416807050L; 55 56 // setup to use Unsafe.compareAndSwapInt for updates 57 private static final Unsafe unsafe = Unsafe.getUnsafe(); 58 private static final long valueOffset; 59 60 static { 61 try { 62 valueOffset = unsafe.objectFieldOffset 63 (AtomicInteger.class.getDeclaredField("value")); 64 } catch (Exception ex) { throw new Error(ex); } 65 } 66 67 private volatile int value; 68 69 /** 70 * Creates a new AtomicInteger with the given initial value. 71 * 72 * @param initialValue the initial value 73 */ 74 public AtomicInteger(int initialValue) { 75 value = initialValue; 76 } 77 78 /** 79 * Creates a new AtomicInteger with initial value {@code 0}. 80 */ 81 public AtomicInteger() { 82 } 83 84 /** 85 * Gets the current value. 86 * 87 * @return the current value 88 */ 89 public final int get() { 90 return value; 91 } 92 93 /** 94 * Sets to the given value. 95 * 96 * @param newValue the new value 97 */ 98 public final void set(int newValue) { 99 value = newValue; 100 } 101 102 /** 103 * Eventually sets to the given value. 104 * 105 * @param newValue the new value 106 * @since 1.6 107 */ 108 public final void lazySet(int newValue) { 109 unsafe.putOrderedInt(this, valueOffset, newValue); 110 } 111 112 /** 113 * Atomically sets to the given value and returns the old value. 114 * 115 * @param newValue the new value 116 * @return the previous value 117 */ 118 public final int getAndSet(int newValue) { 119 for (;;) { 120 int current = get(); 121 if (compareAndSet(current, newValue)) 122 return current; 123 } 124 } 125 126 /** 127 * Atomically sets the value to the given updated value 128 * if the current value {@code ==} the expected value. 129 * 130 * @param expect the expected value 131 * @param update the new value 132 * @return true if successful. False return indicates that 133 * the actual value was not equal to the expected value. 134 */ 135 public final boolean compareAndSet(int expect, int update) { 136 return unsafe.compareAndSwapInt(this, valueOffset, expect, update); 137 } 138 139 /** 140 * Sets the value by applying the supplied operator to the old value, 141 * and updating it atomically as in {@link #compareAndSet(int, int)}. 142 * 143 * If the update results in a collision, we back off and retry the update 144 * (using the new current value) until successful. 145 * 146 * @param op the operator to use to compute the new value 147 * @return the old value 148 */ 149 public final int getAndUpdate(IntUnaryOperator op) { 150 int oldValue, newValue; 151 do { 152 oldValue = get(); 153 newValue = op.operate(oldValue); 154 } while (!compareAndSet(oldValue, newValue)); 155 return oldValue; 156 } 157 158 /** 159 * Sets the value by applying the supplied operator to the old value, 160 * and updating it atomically as in {@link #compareAndSet(int, int)}. 161 * 162 * If the update results in a collision, we back off and retry the update 163 * (using the new current value) until successful. 164 * 165 * @param op the operator to use to compute the new value 166 * @return the new value 167 */ 168 public final int updateAndGet(IntUnaryOperator op) { 169 int oldValue, newValue; 170 do { 171 oldValue = get(); 172 newValue = op.operate(oldValue); 173 } while (!compareAndSet(oldValue, newValue)); 174 return newValue; 175 } 176 177 /** 178 * Atomically sets the value to the given updated value 179 * if the current value {@code ==} the expected value. 180 * 181 * <p>May <a href="package-summary.html#Spurious">fail spuriously</a> 182 * and does not provide ordering guarantees, so is only rarely an 183 * appropriate alternative to {@code compareAndSet}. 184 * 185 * @param expect the expected value 186 * @param update the new value 187 * @return true if successful. 188 */ 189 public final boolean weakCompareAndSet(int expect, int update) { 190 return unsafe.compareAndSwapInt(this, valueOffset, expect, update); 191 } 192 193 /** 194 * Atomically increments by one the current value. 195 * 196 * @return the previous value 197 */ 198 public final int getAndIncrement() { 199 for (;;) { 200 int current = get(); 201 int next = current + 1; 202 if (compareAndSet(current, next)) 203 return current; 204 } 205 } 206 207 /** 208 * Atomically decrements by one the current value. 209 * 210 * @return the previous value 211 */ 212 public final int getAndDecrement() { 213 for (;;) { 214 int current = get(); 215 int next = current - 1; 216 if (compareAndSet(current, next)) 217 return current; 218 } 219 } 220 221 /** 222 * Atomically adds the given value to the current value. 223 * 224 * @param delta the value to add 225 * @return the previous value 226 */ 227 public final int getAndAdd(int delta) { 228 for (;;) { 229 int current = get(); 230 int next = current + delta; 231 if (compareAndSet(current, next)) 232 return current; 233 } 234 } 235 236 /** 237 * Atomically increments by one the current value. 238 * 239 * @return the updated value 240 */ 241 public final int incrementAndGet() { 242 for (;;) { 243 int current = get(); 244 int next = current + 1; 245 if (compareAndSet(current, next)) 246 return next; 247 } 248 } 249 250 /** 251 * Atomically decrements by one the current value. 252 * 253 * @return the updated value 254 */ 255 public final int decrementAndGet() { 256 for (;;) { 257 int current = get(); 258 int next = current - 1; 259 if (compareAndSet(current, next)) 260 return next; 261 } 262 } 263 264 /** 265 * Atomically adds the given value to the current value. 266 * 267 * @param delta the value to add 268 * @return the updated value 269 */ 270 public final int addAndGet(int delta) { 271 for (;;) { 272 int current = get(); 273 int next = current + delta; 274 if (compareAndSet(current, next)) 275 return next; 276 } 277 } 278 279 /** 280 * Returns the String representation of the current value. 281 * @return the String representation of the current value. 282 */ 283 public String toString() { 284 return Integer.toString(get()); 285 } 286 287 288 /** 289 * Returns the value of this {@code AtomicInteger} as an {@code int}. 290 */ 291 public int intValue() { 292 return get(); 293 } 294 295 /** 296 * Returns the value of this {@code AtomicInteger} as a {@code long} 297 * after a widening primitive conversion. 298 * @jls 5.1.2 Widening Primitive Conversions 299 */ 300 public long longValue() { 301 return (long)get(); 302 } 303 304 /** 305 * Returns the value of this {@code AtomicInteger} as a {@code float} 306 * after a widening primitive conversion. 307 * @jls 5.1.2 Widening Primitive Conversions 308 */ 309 public float floatValue() { 310 return (float)get(); 311 } 312 313 /** 314 * Returns the value of this {@code AtomicInteger} as a {@code double} 315 * after a widening primitive conversion. 316 * @jls 5.1.2 Widening Primitive Conversions 317 */ 318 public double doubleValue() { 319 return (double)get(); 320 } 321 322 }