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
7 package java.util.concurrent.atomic;
8 import sun.misc.Unsafe;
11 * A <tt>long</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>AtomicLong</tt> is used in applications such as atomically
15 * incremented sequence numbers, and cannot be used as a replacement
16 * for a {@link java.lang.Long}. However, this class does extend
17 * <tt>Number</tt> to allow uniform access by tools and utilities that
18 * deal with numerically-based classes.
23 public class AtomicLong extends Number implements java.io.Serializable {
24 private static final long serialVersionUID = 1927816293512124184L;
26 // setup to use Unsafe.compareAndSwapLong for updates
27 private static final Unsafe unsafe = Unsafe.getUnsafe();
28 private static final long valueOffset;
31 * Records whether the underlying JVM supports lockless
32 * CompareAndSet for longs. While the unsafe.CompareAndSetLong
33 * method works in either case, some constructions should be
34 * handled at Java level to avoid locking user-visible locks.
36 static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8();
39 * Returns whether underlying JVM supports lockless CompareAndSet
40 * for longs. Called only once and cached in VM_SUPPORTS_LONG_CAS.
42 private static native boolean VMSupportsCS8();
46 valueOffset = unsafe.objectFieldOffset
47 (AtomicLong.class.getDeclaredField("value"));
48 } catch (Exception ex) { throw new Error(ex); }
51 private volatile long value;
54 * Creates a new AtomicLong with the given initial value.
56 * @param initialValue the initial value
58 public AtomicLong(long initialValue) {
63 * Creates a new AtomicLong with initial value <tt>0</tt>.
69 * Gets the current value.
71 * @return the current value
73 public final long get() {
78 * Sets to the given value.
80 * @param newValue the new value
82 public final void set(long newValue) {
87 * Eventually sets to the given value.
89 * @param newValue the new value
92 public final void lazySet(long newValue) {
93 unsafe.putOrderedLong(this, valueOffset, newValue);
97 * Atomically sets to the given value and returns the old value.
99 * @param newValue the new value
100 * @return the previous value
102 public final long getAndSet(long newValue) {
104 long current = get();
105 if (compareAndSet(current, newValue))
111 * Atomically sets the value to the given updated value
112 * if the current value <tt>==</tt> the expected value.
114 * @param expect the expected value
115 * @param update the new value
116 * @return true if successful. False return indicates that
117 * the actual value was not equal to the expected value.
119 public final boolean compareAndSet(long expect, long update) {
120 return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
124 * Atomically sets the value to the given updated value
125 * if the current value <tt>==</tt> the expected value.
126 * May fail spuriously and does not provide ordering guarantees,
127 * so is only rarely an appropriate alternative to <tt>compareAndSet</tt>.
129 * @param expect the expected value
130 * @param update the new value
131 * @return true if successful.
133 public final boolean weakCompareAndSet(long expect, long update) {
134 return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
138 * Atomically increments by one the current value.
140 * @return the previous value
142 public final long getAndIncrement() {
144 long current = get();
145 long next = current + 1;
146 if (compareAndSet(current, next))
152 * Atomically decrements by one the current value.
154 * @return the previous value
156 public final long getAndDecrement() {
158 long current = get();
159 long next = current - 1;
160 if (compareAndSet(current, next))
166 * Atomically adds the given value to the current value.
168 * @param delta the value to add
169 * @return the previous value
171 public final long getAndAdd(long delta) {
173 long current = get();
174 long next = current + delta;
175 if (compareAndSet(current, next))
181 * Atomically increments by one the current value.
183 * @return the updated value
185 public final long incrementAndGet() {
187 long current = get();
188 long next = current + 1;
189 if (compareAndSet(current, next))
195 * Atomically decrements by one the current value.
197 * @return the updated value
199 public final long decrementAndGet() {
201 long current = get();
202 long next = current - 1;
203 if (compareAndSet(current, next))
209 * Atomically adds the given value to the current value.
211 * @param delta the value to add
212 * @return the updated value
214 public final long addAndGet(long delta) {
216 long current = get();
217 long next = current + delta;
218 if (compareAndSet(current, next))
224 * Returns the String representation of the current value.
225 * @return the String representation of the current value.
227 public String toString() {
228 return Long.toString(get());
232 public int intValue() {
236 public long longValue() {
240 public float floatValue() {
244 public double doubleValue() {
245 return (double)get();