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