001: /*
002: * Written by Doug Lea with assistance from members of JCP JSR-166
003: * Expert Group and released to the public domain, as explained at
004: * http://creativecommons.org/licenses/publicdomain
005: */
006:
007: package java.util.concurrent.atomic;
008:
009: import sun.misc.Unsafe;
010:
011: /**
012: * An <tt>int</tt> value that may be updated atomically. See the
013: * {@link java.util.concurrent.atomic} package specification for
014: * description of the properties of atomic variables. An
015: * <tt>AtomicInteger</tt> is used in applications such as atomically
016: * incremented counters, and cannot be used as a replacement for an
017: * {@link java.lang.Integer}. However, this class does extend
018: * <tt>Number</tt> to allow uniform access by tools and utilities that
019: * deal with numerically-based classes.
020: *
021: *
022: * @since 1.5
023: * @author Doug Lea
024: */
025: public class AtomicInteger extends Number implements
026: java.io.Serializable {
027: private static final long serialVersionUID = 6214790243416807050L;
028:
029: // setup to use Unsafe.compareAndSwapInt for updates
030: private static final Unsafe unsafe = Unsafe.getUnsafe();
031: private static final long valueOffset;
032:
033: static {
034: try {
035: valueOffset = unsafe.objectFieldOffset(AtomicInteger.class
036: .getDeclaredField("value"));
037: } catch (Exception ex) {
038: throw new Error(ex);
039: }
040: }
041:
042: private volatile int value;
043:
044: /**
045: * Create a new AtomicInteger with the given initial value.
046: *
047: * @param initialValue the initial value
048: */
049: public AtomicInteger(int initialValue) {
050: value = initialValue;
051: }
052:
053: /**
054: * Create a new AtomicInteger with initial value <tt>0</tt>.
055: */
056: public AtomicInteger() {
057: }
058:
059: /**
060: * Get the current value.
061: *
062: * @return the current value
063: */
064: public final int get() {
065: return value;
066: }
067:
068: /**
069: * Set to the given value.
070: *
071: * @param newValue the new value
072: */
073: public final void set(int newValue) {
074: value = newValue;
075: }
076:
077: /**
078: * Set to the give value and return the old value.
079: *
080: * @param newValue the new value
081: * @return the previous value
082: */
083: public final int getAndSet(int newValue) {
084: for (;;) {
085: int current = get();
086: if (compareAndSet(current, newValue))
087: return current;
088: }
089: }
090:
091: /**
092: * Atomically set the value to the given updated value
093: * if the current value <tt>==</tt> the expected value.
094: * @param expect the expected value
095: * @param update the new value
096: * @return true if successful. False return indicates that
097: * the actual value was not equal to the expected value.
098: */
099: public final boolean compareAndSet(int expect, int update) {
100: return unsafe.compareAndSwapInt(this , valueOffset, expect,
101: update);
102: }
103:
104: /**
105: * Atomically set the value to the given updated value
106: * if the current value <tt>==</tt> the expected value.
107: * May fail spuriously.
108: * @param expect the expected value
109: * @param update the new value
110: * @return true if successful.
111: */
112: public final boolean weakCompareAndSet(int expect, int update) {
113: return unsafe.compareAndSwapInt(this , valueOffset, expect,
114: update);
115: }
116:
117: /**
118: * Atomically increment by one the current value.
119: * @return the previous value
120: */
121: public final int getAndIncrement() {
122: for (;;) {
123: int current = get();
124: int next = current + 1;
125: if (compareAndSet(current, next))
126: return current;
127: }
128: }
129:
130: /**
131: * Atomically decrement by one the current value.
132: * @return the previous value
133: */
134: public final int getAndDecrement() {
135: for (;;) {
136: int current = get();
137: int next = current - 1;
138: if (compareAndSet(current, next))
139: return current;
140: }
141: }
142:
143: /**
144: * Atomically add the given value to current value.
145: * @param delta the value to add
146: * @return the previous value
147: */
148: public final int getAndAdd(int delta) {
149: for (;;) {
150: int current = get();
151: int next = current + delta;
152: if (compareAndSet(current, next))
153: return current;
154: }
155: }
156:
157: /**
158: * Atomically increment by one the current value.
159: * @return the updated value
160: */
161: public final int incrementAndGet() {
162: for (;;) {
163: int current = get();
164: int next = current + 1;
165: if (compareAndSet(current, next))
166: return next;
167: }
168: }
169:
170: /**
171: * Atomically decrement by one the current value.
172: * @return the updated value
173: */
174: public final int decrementAndGet() {
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 add the given value to current value.
185: * @param delta the value to add
186: * @return the updated value
187: */
188: public final int addAndGet(int delta) {
189: for (;;) {
190: int current = get();
191: int next = current + delta;
192: if (compareAndSet(current, next))
193: return next;
194: }
195: }
196:
197: /**
198: * Returns the String representation of the current value.
199: * @return the String representation of the current value.
200: */
201: public String toString() {
202: return Integer.toString(get());
203: }
204:
205: public int intValue() {
206: return get();
207: }
208:
209: public long longValue() {
210: return (long) get();
211: }
212:
213: public float floatValue() {
214: return (float) get();
215: }
216:
217: public double doubleValue() {
218: return (double) get();
219: }
220:
221: }
|