1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * by Oracle in the LICENSE file that accompanied this code. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 /* 26 * This file is available under and governed by the GNU General Public 27 * License version 2 only, as published by the Free Software Foundation. 28 * However, the following notice accompanied the original version of this 29 * file: 30 * 31 * Written by Doug Lea with assistance from members of JCP JSR-166 32 * Expert Group and released to the public domain, as explained at 33 * http://creativecommons.org/publicdomain/zero/1.0/ 34 */ 35 36 package java.util.concurrent.atomic; 37 38 import java.util.function.LongBinaryOperator; 39 import java.util.function.LongUnaryOperator; 40 41 /** 42 * A {@code long} value that may be updated atomically. See the 43 * {@link java.util.concurrent.atomic} package specification for 44 * description of the properties of atomic variables. An 45 * {@code AtomicLong} is used in applications such as atomically 46 * incremented sequence numbers, and cannot be used as a replacement 47 * for a {@link java.lang.Long}. However, this class does extend 48 * {@code Number} to allow uniform access by tools and utilities that 49 * deal with numerically-based classes. 50 * 51 * @since 1.5 52 * @author Doug Lea 53 */ 54 public class AtomicLong extends Number implements java.io.Serializable { 55 private static final long serialVersionUID = 1927816293512124184L; 56 57 private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); 58 private static final long VALUE; 59 60 /** 61 * Records whether the underlying JVM supports lockless 62 * compareAndSwap for longs. While the Unsafe.compareAndSwapLong 63 * method works in either case, some constructions should be 64 * handled at Java level to avoid locking user-visible locks. 65 */ 66 static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8(); 67 68 /** 69 * Returns whether underlying JVM supports lockless CompareAndSet 70 * for longs. Called only once and cached in VM_SUPPORTS_LONG_CAS. 71 */ VMSupportsCS8()72 private static native boolean VMSupportsCS8(); 73 74 static { 75 try { 76 VALUE = U.objectFieldOffset 77 (AtomicLong.class.getDeclaredField("value")); 78 } catch (ReflectiveOperationException e) { 79 throw new Error(e); 80 } 81 } 82 83 private volatile long value; 84 85 /** 86 * Creates a new AtomicLong with the given initial value. 87 * 88 * @param initialValue the initial value 89 */ AtomicLong(long initialValue)90 public AtomicLong(long initialValue) { 91 value = initialValue; 92 } 93 94 /** 95 * Creates a new AtomicLong with initial value {@code 0}. 96 */ AtomicLong()97 public AtomicLong() { 98 } 99 100 /** 101 * Gets the current value. 102 * 103 * @return the current value 104 */ get()105 public final long get() { 106 return value; 107 } 108 109 /** 110 * Sets to the given value. 111 * 112 * @param newValue the new value 113 */ set(long newValue)114 public final void set(long newValue) { 115 // Use putLongVolatile instead of ordinary volatile store when 116 // using compareAndSwapLong, for sake of some 32bit systems. 117 U.putLongVolatile(this, VALUE, newValue); 118 } 119 120 /** 121 * Eventually sets to the given value. 122 * 123 * @param newValue the new value 124 * @since 1.6 125 */ lazySet(long newValue)126 public final void lazySet(long newValue) { 127 U.putOrderedLong(this, VALUE, newValue); 128 } 129 130 /** 131 * Atomically sets to the given value and returns the old value. 132 * 133 * @param newValue the new value 134 * @return the previous value 135 */ getAndSet(long newValue)136 public final long getAndSet(long newValue) { 137 return U.getAndSetLong(this, VALUE, newValue); 138 } 139 140 /** 141 * Atomically sets the value to the given updated value 142 * if the current value {@code ==} the expected value. 143 * 144 * @param expect the expected value 145 * @param update the new value 146 * @return {@code true} if successful. False return indicates that 147 * the actual value was not equal to the expected value. 148 */ compareAndSet(long expect, long update)149 public final boolean compareAndSet(long expect, long update) { 150 return U.compareAndSwapLong(this, VALUE, expect, update); 151 } 152 153 /** 154 * Atomically sets the value to the given updated value 155 * if the current value {@code ==} the expected value. 156 * 157 * <p><a href="package-summary.html#weakCompareAndSet">May fail 158 * spuriously and does not provide ordering guarantees</a>, so is 159 * only rarely an appropriate alternative to {@code compareAndSet}. 160 * 161 * @param expect the expected value 162 * @param update the new value 163 * @return {@code true} if successful 164 */ weakCompareAndSet(long expect, long update)165 public final boolean weakCompareAndSet(long expect, long update) { 166 return U.compareAndSwapLong(this, VALUE, expect, update); 167 } 168 169 /** 170 * Atomically increments by one the current value. 171 * 172 * @return the previous value 173 */ getAndIncrement()174 public final long getAndIncrement() { 175 return U.getAndAddLong(this, VALUE, 1L); 176 } 177 178 /** 179 * Atomically decrements by one the current value. 180 * 181 * @return the previous value 182 */ getAndDecrement()183 public final long getAndDecrement() { 184 return U.getAndAddLong(this, VALUE, -1L); 185 } 186 187 /** 188 * Atomically adds the given value to the current value. 189 * 190 * @param delta the value to add 191 * @return the previous value 192 */ getAndAdd(long delta)193 public final long getAndAdd(long delta) { 194 return U.getAndAddLong(this, VALUE, delta); 195 } 196 197 /** 198 * Atomically increments by one the current value. 199 * 200 * @return the updated value 201 */ incrementAndGet()202 public final long incrementAndGet() { 203 return U.getAndAddLong(this, VALUE, 1L) + 1L; 204 } 205 206 /** 207 * Atomically decrements by one the current value. 208 * 209 * @return the updated value 210 */ decrementAndGet()211 public final long decrementAndGet() { 212 return U.getAndAddLong(this, VALUE, -1L) - 1L; 213 } 214 215 /** 216 * Atomically adds the given value to the current value. 217 * 218 * @param delta the value to add 219 * @return the updated value 220 */ addAndGet(long delta)221 public final long addAndGet(long delta) { 222 return U.getAndAddLong(this, VALUE, delta) + delta; 223 } 224 225 /** 226 * Atomically updates the current value with the results of 227 * applying the given function, returning the previous value. The 228 * function should be side-effect-free, since it may be re-applied 229 * when attempted updates fail due to contention among threads. 230 * 231 * @param updateFunction a side-effect-free function 232 * @return the previous value 233 * @since 1.8 234 */ getAndUpdate(LongUnaryOperator updateFunction)235 public final long getAndUpdate(LongUnaryOperator updateFunction) { 236 long prev, next; 237 do { 238 prev = get(); 239 next = updateFunction.applyAsLong(prev); 240 } while (!compareAndSet(prev, next)); 241 return prev; 242 } 243 244 /** 245 * Atomically updates the current value with the results of 246 * applying the given function, returning the updated value. The 247 * function should be side-effect-free, since it may be re-applied 248 * when attempted updates fail due to contention among threads. 249 * 250 * @param updateFunction a side-effect-free function 251 * @return the updated value 252 * @since 1.8 253 */ updateAndGet(LongUnaryOperator updateFunction)254 public final long updateAndGet(LongUnaryOperator updateFunction) { 255 long prev, next; 256 do { 257 prev = get(); 258 next = updateFunction.applyAsLong(prev); 259 } while (!compareAndSet(prev, next)); 260 return next; 261 } 262 263 /** 264 * Atomically updates the current value with the results of 265 * applying the given function to the current and given values, 266 * returning the previous value. The function should be 267 * side-effect-free, since it may be re-applied when attempted 268 * updates fail due to contention among threads. The function 269 * is applied with the current value as its first argument, 270 * and the given update as the second argument. 271 * 272 * @param x the update value 273 * @param accumulatorFunction a side-effect-free function of two arguments 274 * @return the previous value 275 * @since 1.8 276 */ getAndAccumulate(long x, LongBinaryOperator accumulatorFunction)277 public final long getAndAccumulate(long x, 278 LongBinaryOperator accumulatorFunction) { 279 long prev, next; 280 do { 281 prev = get(); 282 next = accumulatorFunction.applyAsLong(prev, x); 283 } while (!compareAndSet(prev, next)); 284 return prev; 285 } 286 287 /** 288 * Atomically updates the current value with the results of 289 * applying the given function to the current and given values, 290 * returning the updated value. The function should be 291 * side-effect-free, since it may be re-applied when attempted 292 * updates fail due to contention among threads. The function 293 * is applied with the current value as its first argument, 294 * and the given update as the second argument. 295 * 296 * @param x the update value 297 * @param accumulatorFunction a side-effect-free function of two arguments 298 * @return the updated value 299 * @since 1.8 300 */ accumulateAndGet(long x, LongBinaryOperator accumulatorFunction)301 public final long accumulateAndGet(long x, 302 LongBinaryOperator accumulatorFunction) { 303 long prev, next; 304 do { 305 prev = get(); 306 next = accumulatorFunction.applyAsLong(prev, x); 307 } while (!compareAndSet(prev, next)); 308 return next; 309 } 310 311 /** 312 * Returns the String representation of the current value. 313 * @return the String representation of the current value 314 */ toString()315 public String toString() { 316 return Long.toString(get()); 317 } 318 319 /** 320 * Returns the value of this {@code AtomicLong} as an {@code int} 321 * after a narrowing primitive conversion. 322 * @jls 5.1.3 Narrowing Primitive Conversions 323 */ intValue()324 public int intValue() { 325 return (int)get(); 326 } 327 328 /** 329 * Returns the value of this {@code AtomicLong} as a {@code long}. 330 * Equivalent to {@link #get()}. 331 */ longValue()332 public long longValue() { 333 return get(); 334 } 335 336 /** 337 * Returns the value of this {@code AtomicLong} as a {@code float} 338 * after a widening primitive conversion. 339 * @jls 5.1.2 Widening Primitive Conversions 340 */ floatValue()341 public float floatValue() { 342 return (float)get(); 343 } 344 345 /** 346 * Returns the value of this {@code AtomicLong} as a {@code double} 347 * after a widening primitive conversion. 348 * @jls 5.1.2 Widening Primitive Conversions 349 */ doubleValue()350 public double doubleValue() { 351 return (double)get(); 352 } 353 354 } 355