Source for java.util.concurrent.atomic.AtomicInteger

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