JDK1.8源码解析之AtomicLong

378 阅读1分钟

前言

  • 和AtomicInt极其相似
  • 一个{@code long}值,可以自动更新。
  • 有关原子变量的属性的描述,请参见{@link java.util.concurrent.atomic}包规范。
  • {@code AtomicLong}用于诸如原子递增序列号之类的应用程序,并且不能替代{@link java.lang.Long}。
  • 但是,此类确实扩展了{@code Number},以允许处理基于数字的类的工具和实用程序进行统一访问。

源码

public class AtomicLong extends Number implements java.io.Serializable { private static final long serialVersionUID = 1927816293512124184L;

private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;

static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8();

private static native boolean VMSupportsCS8();

static {
    try {
        valueOffset = unsafe.objectFieldOffset
            (AtomicLong.class.getDeclaredField("value"));
    } catch (Exception ex) { throw new Error(ex); }
}

private volatile long value;

public AtomicLong(long initialValue) {
    value = initialValue;
}

public AtomicLong() {
}


public final long get() {
    return value;
}


public final void set(long newValue) {
    value = newValue;
}

public final void lazySet(long newValue) {
    unsafe.putOrderedLong(this, valueOffset, newValue);
}


public final long getAndSet(long newValue) {
    return unsafe.getAndSetLong(this, valueOffset, newValue);
}

public final boolean compareAndSet(long expect, long update) {
    return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
}

public final boolean weakCompareAndSet(long expect, long update) {
    return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
}

/**
 * Atomically increments by one the current value.
 *
 * @return the previous value
 */
public final long getAndIncrement() {
    return unsafe.getAndAddLong(this, valueOffset, 1L);
}


public final long getAndDecrement() {
    return unsafe.getAndAddLong(this, valueOffset, -1L);
}


public final long getAndAdd(long delta) {
    return unsafe.getAndAddLong(this, valueOffset, delta);
}


public final long incrementAndGet() {
    return unsafe.getAndAddLong(this, valueOffset, 1L) + 1L;
}


public final long decrementAndGet() {
    return unsafe.getAndAddLong(this, valueOffset, -1L) - 1L;
}

public final long addAndGet(long delta) {
    return unsafe.getAndAddLong(this, valueOffset, delta) + delta;
}


public final long getAndUpdate(LongUnaryOperator updateFunction) {
    long prev, next;
    do {
        prev = get();
        next = updateFunction.applyAsLong(prev);
    } while (!compareAndSet(prev, next));
    return prev;
}


public final long updateAndGet(LongUnaryOperator updateFunction) {
    long prev, next;
    do {
        prev = get();
        next = updateFunction.applyAsLong(prev);
    } while (!compareAndSet(prev, next));
    return next;
}


public final long getAndAccumulate(long x,
                                   LongBinaryOperator accumulatorFunction) {
    long prev, next;
    do {
        prev = get();
        next = accumulatorFunction.applyAsLong(prev, x);
    } while (!compareAndSet(prev, next));
    return prev;
}

public final long accumulateAndGet(long x,
                                   LongBinaryOperator accumulatorFunction) {
    long prev, next;
    do {
        prev = get();
        next = accumulatorFunction.applyAsLong(prev, x);
    } while (!compareAndSet(prev, next));
    return next;
}

public String toString() {
    return Long.toString(get());
}

public int intValue() {
    return (int)get();
}

public long longValue() {
    return get();
}


public float floatValue() {
    return (float)get();
}

public double doubleValue() {
    return (double)get();
}

}