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 7package java.util.concurrent.atomic; 8 9import sun.misc.Unsafe; 10 11/** 12 * An {@code int} value that may be updated atomically. See the 13 * {@link java.util.concurrent.atomic} package specification for 14 * description of the properties of atomic variables. An 15 * {@code AtomicInteger} is used in applications such as atomically 16 * incremented counters, and cannot be used as a replacement for an 17 * {@link java.lang.Integer}. However, this class does extend 18 * {@code Number} to allow uniform access by tools and utilities that 19 * deal with numerically-based classes. 20 * 21 * @since 1.5 22 * @author Doug Lea 23*/ 24public class AtomicInteger extends Number implements java.io.Serializable { 25 private static final long serialVersionUID = 6214790243416807050L; 26 27 // setup to use Unsafe.compareAndSwapInt for updates 28 private static final Unsafe unsafe = Unsafe.getUnsafe(); 29 private static final long valueOffset; 30 31 static { 32 try { 33 valueOffset = unsafe.objectFieldOffset 34 (AtomicInteger.class.getDeclaredField("value")); 35 } catch (Exception ex) { throw new Error(ex); } 36 } 37 38 private volatile int value; 39 40 /** 41 * Creates a new AtomicInteger with the given initial value. 42 * 43 * @param initialValue the initial value 44 */ 45 public AtomicInteger(int initialValue) { 46 value = initialValue; 47 } 48 49 /** 50 * Creates a new AtomicInteger with initial value {@code 0}. 51 */ 52 public AtomicInteger() { 53 } 54 55 /** 56 * Gets the current value. 57 * 58 * @return the current value 59 */ 60 public final int get() { 61 return value; 62 } 63 64 /** 65 * Sets to the given value. 66 * 67 * @param newValue the new value 68 */ 69 public final void set(int newValue) { 70 value = newValue; 71 } 72 73 /** 74 * Eventually sets to the given value. 75 * 76 * @param newValue the new value 77 * @since 1.6 78 */ 79 public final void lazySet(int newValue) { 80 unsafe.putOrderedInt(this, valueOffset, newValue); 81 } 82 83 /** 84 * Atomically sets to the given value and returns the old value. 85 * 86 * @param newValue the new value 87 * @return the previous value 88 */ 89 public final int getAndSet(int newValue) { 90 for (;;) { 91 int current = get(); 92 if (compareAndSet(current, newValue)) 93 return current; 94 } 95 } 96 97 /** 98 * Atomically sets the value to the given updated value 99 * if the current value {@code ==} the expected value. 100 * 101 * @param expect the expected value 102 * @param update the new value 103 * @return true if successful. False return indicates that 104 * the actual value was not equal to the expected value. 105 */ 106 public final boolean compareAndSet(int expect, int update) { 107 return unsafe.compareAndSwapInt(this, valueOffset, expect, update); 108 } 109 110 /** 111 * Atomically sets the value to the given updated value 112 * if the current value {@code ==} the expected value. 113 * 114 * <p><a href="package-summary.html#weakCompareAndSet">May fail 115 * spuriously and does not provide ordering guarantees</a>, so is 116 * only rarely an appropriate alternative to {@code compareAndSet}. 117 * 118 * @param expect the expected value 119 * @param update the new value 120 * @return true if successful 121 */ 122 public final boolean weakCompareAndSet(int expect, int update) { 123 return unsafe.compareAndSwapInt(this, valueOffset, expect, update); 124 } 125 126 /** 127 * Atomically increments by one the current value. 128 * 129 * @return the previous value 130 */ 131 public final int getAndIncrement() { 132 for (;;) { 133 int current = get(); 134 int next = current + 1; 135 if (compareAndSet(current, next)) 136 return current; 137 } 138 } 139 140 /** 141 * Atomically decrements by one the current value. 142 * 143 * @return the previous value 144 */ 145 public final int getAndDecrement() { 146 for (;;) { 147 int current = get(); 148 int next = current - 1; 149 if (compareAndSet(current, next)) 150 return current; 151 } 152 } 153 154 /** 155 * Atomically adds the given value to the current value. 156 * 157 * @param delta the value to add 158 * @return the previous value 159 */ 160 public final int getAndAdd(int delta) { 161 for (;;) { 162 int current = get(); 163 int next = current + delta; 164 if (compareAndSet(current, next)) 165 return current; 166 } 167 } 168 169 /** 170 * Atomically increments by one the current value. 171 * 172 * @return the updated value 173 */ 174 public final int incrementAndGet() { 175 for (;;) { 176 int current = get(); 177 int next = current + 1; 178 if (compareAndSet(current, next)) 179 return next; 180 } 181 } 182 183 /** 184 * Atomically decrements by one the current value. 185 * 186 * @return the updated value 187 */ 188 public final int decrementAndGet() { 189 for (;;) { 190 int current = get(); 191 int next = current - 1; 192 if (compareAndSet(current, next)) 193 return next; 194 } 195 } 196 197 /** 198 * Atomically adds the given value to the current value. 199 * 200 * @param delta the value to add 201 * @return the updated value 202 */ 203 public final int addAndGet(int delta) { 204 for (;;) { 205 int current = get(); 206 int next = current + delta; 207 if (compareAndSet(current, next)) 208 return next; 209 } 210 } 211 212 /** 213 * Returns the String representation of the current value. 214 * @return the String representation of the current value 215 */ 216 public String toString() { 217 return Integer.toString(get()); 218 } 219 220 /** 221 * Returns the value of this {@code AtomicInteger} as an {@code int}. 222 */ 223 public int intValue() { 224 return get(); 225 } 226 227 /** 228 * Returns the value of this {@code AtomicInteger} as a {@code long} 229 * after a widening primitive conversion. 230 */ 231 public long longValue() { 232 return (long)get(); 233 } 234 235 /** 236 * Returns the value of this {@code AtomicInteger} as a {@code float} 237 * after a widening primitive conversion. 238 */ 239 public float floatValue() { 240 return (float)get(); 241 } 242 243 /** 244 * Returns the value of this {@code AtomicInteger} as a {@code double} 245 * after a widening primitive conversion. 246 */ 247 public double doubleValue() { 248 return (double)get(); 249 } 250 251} 252