ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jdk8/java/util/concurrent/atomic/AtomicLong.java
Revision: 1.1
Committed: Sat Mar 26 06:22:51 2016 UTC (8 years, 2 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Log Message:
fork jdk8 maintenance branch for source and jtreg tests

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 java.util.function.LongBinaryOperator;
10 import java.util.function.LongUnaryOperator;
11
12 /**
13 * A {@code long} value that may be updated atomically. See the
14 * {@link java.util.concurrent.atomic} package specification for
15 * description of the properties of atomic variables. An
16 * {@code AtomicLong} is used in applications such as atomically
17 * incremented sequence numbers, and cannot be used as a replacement
18 * for a {@link java.lang.Long}. However, this class does extend
19 * {@code Number} to allow uniform access by tools and utilities that
20 * deal with numerically-based classes.
21 *
22 * @since 1.5
23 * @author Doug Lea
24 */
25 public class AtomicLong extends Number implements java.io.Serializable {
26 private static final long serialVersionUID = 1927816293512124184L;
27
28 private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
29 private static final long VALUE;
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 VALUE = U.objectFieldOffset
48 (AtomicLong.class.getDeclaredField("value"));
49 } catch (ReflectiveOperationException e) {
50 throw new Error(e);
51 }
52 }
53
54 private volatile long value;
55
56 /**
57 * Creates a new AtomicLong with the given initial value.
58 *
59 * @param initialValue the initial value
60 */
61 public AtomicLong(long initialValue) {
62 value = initialValue;
63 }
64
65 /**
66 * Creates a new AtomicLong with initial value {@code 0}.
67 */
68 public AtomicLong() {
69 }
70
71 /**
72 * Gets the current value.
73 *
74 * @return the current value
75 */
76 public final long get() {
77 return value;
78 }
79
80 /**
81 * Sets to the given value.
82 *
83 * @param newValue the new value
84 */
85 public final void set(long newValue) {
86 // Use putLongVolatile instead of ordinary volatile store when
87 // using compareAndSwapLong, for sake of some 32bit systems.
88 U.putLongVolatile(this, VALUE, newValue);
89 }
90
91 /**
92 * Eventually sets to the given value.
93 *
94 * @param newValue the new value
95 * @since 1.6
96 */
97 public final void lazySet(long newValue) {
98 U.putOrderedLong(this, VALUE, newValue);
99 }
100
101 /**
102 * Atomically sets to the given value and returns the old value.
103 *
104 * @param newValue the new value
105 * @return the previous value
106 */
107 public final long getAndSet(long newValue) {
108 return U.getAndSetLong(this, VALUE, newValue);
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 {@code 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 U.compareAndSwapLong(this, VALUE, 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 {@code true} if successful
135 */
136 public final boolean weakCompareAndSet(long expect, long update) {
137 return U.compareAndSwapLong(this, VALUE, 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 return U.getAndAddLong(this, VALUE, 1L);
147 }
148
149 /**
150 * Atomically decrements by one the current value.
151 *
152 * @return the previous value
153 */
154 public final long getAndDecrement() {
155 return U.getAndAddLong(this, VALUE, -1L);
156 }
157
158 /**
159 * Atomically adds the given value to the current value.
160 *
161 * @param delta the value to add
162 * @return the previous value
163 */
164 public final long getAndAdd(long delta) {
165 return U.getAndAddLong(this, VALUE, delta);
166 }
167
168 /**
169 * Atomically increments by one the current value.
170 *
171 * @return the updated value
172 */
173 public final long incrementAndGet() {
174 return U.getAndAddLong(this, VALUE, 1L) + 1L;
175 }
176
177 /**
178 * Atomically decrements by one the current value.
179 *
180 * @return the updated value
181 */
182 public final long decrementAndGet() {
183 return U.getAndAddLong(this, VALUE, -1L) - 1L;
184 }
185
186 /**
187 * Atomically adds the given value to the current value.
188 *
189 * @param delta the value to add
190 * @return the updated value
191 */
192 public final long addAndGet(long delta) {
193 return U.getAndAddLong(this, VALUE, delta) + delta;
194 }
195
196 /**
197 * Atomically updates the current value with the results of
198 * applying the given function, returning the previous value. The
199 * function should be side-effect-free, since it may be re-applied
200 * when attempted updates fail due to contention among threads.
201 *
202 * @param updateFunction a side-effect-free function
203 * @return the previous value
204 * @since 1.8
205 */
206 public final long getAndUpdate(LongUnaryOperator updateFunction) {
207 long prev, next;
208 do {
209 prev = get();
210 next = updateFunction.applyAsLong(prev);
211 } while (!compareAndSet(prev, next));
212 return prev;
213 }
214
215 /**
216 * Atomically updates the current value with the results of
217 * applying the given function, returning the updated value. The
218 * function should be side-effect-free, since it may be re-applied
219 * when attempted updates fail due to contention among threads.
220 *
221 * @param updateFunction a side-effect-free function
222 * @return the updated value
223 * @since 1.8
224 */
225 public final long updateAndGet(LongUnaryOperator updateFunction) {
226 long prev, next;
227 do {
228 prev = get();
229 next = updateFunction.applyAsLong(prev);
230 } while (!compareAndSet(prev, next));
231 return next;
232 }
233
234 /**
235 * Atomically updates the current value with the results of
236 * applying the given function to the current and given values,
237 * returning the previous value. The function should be
238 * side-effect-free, since it may be re-applied when attempted
239 * updates fail due to contention among threads. The function
240 * is applied with the current value as its first argument,
241 * and the given update as the second argument.
242 *
243 * @param x the update value
244 * @param accumulatorFunction a side-effect-free function of two arguments
245 * @return the previous value
246 * @since 1.8
247 */
248 public final long getAndAccumulate(long x,
249 LongBinaryOperator accumulatorFunction) {
250 long prev, next;
251 do {
252 prev = get();
253 next = accumulatorFunction.applyAsLong(prev, x);
254 } while (!compareAndSet(prev, next));
255 return prev;
256 }
257
258 /**
259 * Atomically updates the current value with the results of
260 * applying the given function to the current and given values,
261 * returning the updated value. The function should be
262 * side-effect-free, since it may be re-applied when attempted
263 * updates fail due to contention among threads. The function
264 * is applied with the current value as its first argument,
265 * and the given update as the second argument.
266 *
267 * @param x the update value
268 * @param accumulatorFunction a side-effect-free function of two arguments
269 * @return the updated value
270 * @since 1.8
271 */
272 public final long accumulateAndGet(long x,
273 LongBinaryOperator accumulatorFunction) {
274 long prev, next;
275 do {
276 prev = get();
277 next = accumulatorFunction.applyAsLong(prev, x);
278 } while (!compareAndSet(prev, next));
279 return next;
280 }
281
282 /**
283 * Returns the String representation of the current value.
284 * @return the String representation of the current value
285 */
286 public String toString() {
287 return Long.toString(get());
288 }
289
290 /**
291 * Returns the value of this {@code AtomicLong} as an {@code int}
292 * after a narrowing primitive conversion.
293 * @jls 5.1.3 Narrowing Primitive Conversions
294 */
295 public int intValue() {
296 return (int)get();
297 }
298
299 /**
300 * Returns the value of this {@code AtomicLong} as a {@code long}.
301 * Equivalent to {@link #get()}.
302 */
303 public long longValue() {
304 return get();
305 }
306
307 /**
308 * Returns the value of this {@code AtomicLong} as a {@code float}
309 * after a widening primitive conversion.
310 * @jls 5.1.2 Widening Primitive Conversions
311 */
312 public float floatValue() {
313 return (float)get();
314 }
315
316 /**
317 * Returns the value of this {@code AtomicLong} as a {@code double}
318 * after a widening primitive conversion.
319 * @jls 5.1.2 Widening Primitive Conversions
320 */
321 public double doubleValue() {
322 return (double)get();
323 }
324
325 }