GNU Classpath (0.98) | |
Frames | No Frames |
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: 7: package java.util.concurrent.atomic; 8: import sun.misc.Unsafe; 9: 10: /** 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. 19: * 20: * @since 1.5 21: * @author Doug Lea 22: */ 23: public class AtomicLong extends Number implements java.io.Serializable { 24: private static final long serialVersionUID = 1927816293512124184L; 25: 26: // setup to use Unsafe.compareAndSwapLong for updates 27: private static final Unsafe unsafe = Unsafe.getUnsafe(); 28: private static final long valueOffset; 29: 30: /** 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. 35: */ 36: static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8(); 37: 38: /** 39: * Returns whether underlying JVM supports lockless CompareAndSet 40: * for longs. Called only once and cached in VM_SUPPORTS_LONG_CAS. 41: */ 42: private static native boolean VMSupportsCS8(); 43: 44: static { 45: try { 46: valueOffset = unsafe.objectFieldOffset 47: (AtomicLong.class.getDeclaredField("value")); 48: } catch (Exception ex) { throw new Error(ex); } 49: } 50: 51: private volatile long value; 52: 53: /** 54: * Creates a new AtomicLong with the given initial value. 55: * 56: * @param initialValue the initial value 57: */ 58: public AtomicLong(long initialValue) { 59: value = initialValue; 60: } 61: 62: /** 63: * Creates a new AtomicLong with initial value <tt>0</tt>. 64: */ 65: public AtomicLong() { 66: } 67: 68: /** 69: * Gets the current value. 70: * 71: * @return the current value 72: */ 73: public final long get() { 74: return value; 75: } 76: 77: /** 78: * Sets to the given value. 79: * 80: * @param newValue the new value 81: */ 82: public final void set(long newValue) { 83: value = newValue; 84: } 85: 86: /** 87: * Eventually sets to the given value. 88: * 89: * @param newValue the new value 90: * @since 1.6 91: */ 92: public final void lazySet(long newValue) { 93: unsafe.putOrderedLong(this, valueOffset, newValue); 94: } 95: 96: /** 97: * Atomically sets to the given value and returns the old value. 98: * 99: * @param newValue the new value 100: * @return the previous value 101: */ 102: public final long getAndSet(long newValue) { 103: while (true) { 104: long current = get(); 105: if (compareAndSet(current, newValue)) 106: return current; 107: } 108: } 109: 110: /** 111: * Atomically sets the value to the given updated value 112: * if the current value <tt>==</tt> the expected value. 113: * 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. 118: */ 119: public final boolean compareAndSet(long expect, long update) { 120: return unsafe.compareAndSwapLong(this, valueOffset, expect, update); 121: } 122: 123: /** 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>. 128: * 129: * @param expect the expected value 130: * @param update the new value 131: * @return true if successful. 132: */ 133: public final boolean weakCompareAndSet(long expect, long update) { 134: return unsafe.compareAndSwapLong(this, valueOffset, expect, update); 135: } 136: 137: /** 138: * Atomically increments by one the current value. 139: * 140: * @return the previous value 141: */ 142: public final long getAndIncrement() { 143: while (true) { 144: long current = get(); 145: long next = current + 1; 146: if (compareAndSet(current, next)) 147: return current; 148: } 149: } 150: 151: /** 152: * Atomically decrements by one the current value. 153: * 154: * @return the previous value 155: */ 156: public final long getAndDecrement() { 157: while (true) { 158: long current = get(); 159: long next = current - 1; 160: if (compareAndSet(current, next)) 161: return current; 162: } 163: } 164: 165: /** 166: * Atomically adds the given value to the current value. 167: * 168: * @param delta the value to add 169: * @return the previous value 170: */ 171: public final long getAndAdd(long delta) { 172: while (true) { 173: long current = get(); 174: long next = current + delta; 175: if (compareAndSet(current, next)) 176: return current; 177: } 178: } 179: 180: /** 181: * Atomically increments by one the current value. 182: * 183: * @return the updated value 184: */ 185: public final long incrementAndGet() { 186: for (;;) { 187: long current = get(); 188: long next = current + 1; 189: if (compareAndSet(current, next)) 190: return next; 191: } 192: } 193: 194: /** 195: * Atomically decrements by one the current value. 196: * 197: * @return the updated value 198: */ 199: public final long decrementAndGet() { 200: for (;;) { 201: long current = get(); 202: long next = current - 1; 203: if (compareAndSet(current, next)) 204: return next; 205: } 206: } 207: 208: /** 209: * Atomically adds the given value to the current value. 210: * 211: * @param delta the value to add 212: * @return the updated value 213: */ 214: public final long addAndGet(long delta) { 215: for (;;) { 216: long current = get(); 217: long next = current + delta; 218: if (compareAndSet(current, next)) 219: return next; 220: } 221: } 222: 223: /** 224: * Returns the String representation of the current value. 225: * @return the String representation of the current value. 226: */ 227: public String toString() { 228: return Long.toString(get()); 229: } 230: 231: 232: public int intValue() { 233: return (int)get(); 234: } 235: 236: public long longValue() { 237: return (long)get(); 238: } 239: 240: public float floatValue() { 241: return (float)get(); 242: } 243: 244: public double doubleValue() { 245: return (double)get(); 246: } 247: 248: }
GNU Classpath (0.98) |