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