ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jdk7/java/util/concurrent/atomic/AtomicLong.java
Revision: 1.4
Committed: Sun Jan 18 20:17:32 2015 UTC (9 years, 4 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +1 -0 lines
Log Message:
exactly one blank line before and after package statements

File Contents

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