JUC-AtomicInteger

2020-08-08 13:21:27

JUC

atomic

class

AtomicInteger

extends Number

對於一個整數的加減操作在多執行緒情況下要保證執行緒安全需要加鎖,而AtomicInteger可以不需要鎖,且效能更好

類註釋
An int value that may be updated atomically.  See the
java.util.concurrent.atomic package specification for
description of the properties of atomic variables. An
AtomicInteger is used in applications such as atomically
incremented counters, and cannot be used as a replacement for an
java.lang.Integer. However, this class does extend
Number to allow uniform access by tools and utilities that
deal with numerically-based classes.
可以原子更新的整型值。見java.util.concurrent.原子封裝規範描述原子變數的屬性。
AtomicInteger用於諸如atomicly之類的應用程式中遞增計數器,並不能替代java.lang.Integer. 
但是,這個類確實擴充套件了允許工具和實用程式統一存取的編號處理基於數位的類
fields
unsafe

Unsafe類使Java擁有了像C語言的指針一樣操作記憶體空間的能力,一旦能夠直接操作記憶體,這也就意味着

  1. 不受jvm管理,也就意味着無法被GC,需要我們手動GC,稍有不慎就會出現記憶體漏失。
  2. Unsafe的不少方法中必須提供原始地址(記憶體地址)和被替換物件的地址,偏移量要自己計算,一旦出現問題就是JVM崩潰級別的異常,會導致整個JVM範例崩潰,表現爲應用程式直接crash掉。
  3. 直接操作記憶體,也意味着其速度更快,在高併發的條件之下能夠很好地提高效率。

一共有82個public native修飾的方法,還有幾十個基於這82個public native方法的其他方法。包括下面 下麪幾類方法:

  1. 初始化操作
  2. 操作物件屬性
  3. 運算元組元素
  4. 執行緒掛起和回覆 回復
  5. CAS機制 機製
// setup to use Unsafe.compareAndSwapInt for updates
//設定Unsafe的cas來更新
private static final Unsafe unsafe = Unsafe.getUnsafe();
valueOffset
private static final long valueOffset;

通過unsafe獲取的value屬性在記憶體中的偏移量(地址值)

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

AtomicInteger類維護的int值

private volatile int value;
constructors

一共有兩個構造方法

一個是傳遞初始值

/**
 * Creates a new AtomicInteger with the given initial value.
 *
 * @param initialValue the initial value
 */
public AtomicInteger(int initialValue) {
    value = initialValue;
}

一個是初始化值爲0

/**
 * Creates a new AtomicInteger with initial value {@code 0}.
 */
public AtomicInteger() {
}
methods
getAndIncrement()

get舊值然後自增1方法(類似於i++),JDK8後基本通過unsafe實現

/**
 * Atomically increments by one the current value.
 * 原子性的給當前值+1
 *
 * @return the previous value
 * 返回之前的值
 */
public final int getAndIncrement() {
    return unsafe.getAndAddInt(this, valueOffset, 1);
}

unsafe的實現

/**
 * 通過CAS對一個Int加 
 * var1 : 自增的物件
 * var2 : 記憶體偏移量(之前的值)
 * var4 : 自增的值
 * var5 : 當前值
 */
public final int getAndAddInt(Object var1, long var2, int var4) {
    int var5;
    do {
        //當前值
        var5 = this.getIntVolatile(var1, var2);
    } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
	//返回更新前的值
    return var5;
}
//本地方法
public native int getIntVolatile(Object var1, long var2);
getAndDecrement()

get舊值然後自減1(類似於i- - ),與getAndIncrement()基本一致

/**
 * Atomically decrements by one the current value.
 *
 * @return the previous value
 */
public final int getAndDecrement() {
    return unsafe.getAndAddInt(this, valueOffset, -1);
}
getAndAdd(int…… delta)

get舊值然後自增delta(數學符號Δ)

/**
 * Atomically adds the given value to the current value.
 *
 * @param delta the value to add
 * @return the previous value
 */
public final int getAndAdd(int delta) {
    return unsafe.getAndAddInt(this, valueOffset, delta);
}
addAndGet(int delta)

先自增delta再返回新值

/**
 * Atomically adds the given value to the current value.
 *
 * @param delta the value to add
 * @return the updated value
 */
public final int addAndGet(int delta) {
    return unsafe.getAndAddInt(this, valueOffset, delta) + delta;
}
incrementAndGet()

自增1然後返回新值(類似於++i)

/**
 * Atomically increments by one the current value.
 *
 * @return the updated value
 */
public final int incrementAndGet() {
    return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}
decrementAndGet()

自減1然後返回新值(類似於 - - i)

/**
 * Atomically decrements by one the current value.
 *
 * @return the updated value
 */
public final int decrementAndGet() {
    return unsafe.getAndAddInt(this, valueOffset, -1) - 1;
}
get() & set() & getAndSet(int newValue)

獲取當前值和設定當前值爲給定值、設定爲給定值然後返回舊值

/**
 * Gets the current value.
 *
 * @return the current value
 */
public final int get() {
    return value;
}

/**
 * Sets to the given value.
 *
 * @param newValue the new value
 */
public final void set(int newValue) {
    value = newValue;
}

	/**
     * Atomically sets to the given value and returns the old value.
     *
     * @param newValue the new value
     * @return the previous value
     */
    public final int getAndSet(int newValue) {
        return unsafe.getAndSetInt(this, valueOffset, newValue);
    }
lazySet(int newValue)

最終設定爲給定值

/**
 * Eventually sets to the given value.
 *
 * @param newValue the new value
 * @since 1.6
 */
public final void lazySet(int newValue) {
    unsafe.putOrderedInt(this, valueOffset, newValue);
}
compareAndSet(int expect, int update)

給定一箇舊值和一個待更新值

如果當前值==預期值expect則更新,返回true

如果當前值!=預期值expect則不更新,返回false

/**
 * Atomically sets the value to the given updated value
 * if the current value == the expected value.
 *
 * @param expect the expected value
 * @param update the new value
 * @return true if successful. False return indicates that
 * the actual value was not equal to the expected value.
 */
public final boolean compareAndSet(int expect, int update) {
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
weakCompareAndSet(int expect, int update)

功能同上,直至JDK8實現細節與compareAndSet一毛一樣

/**
 * Atomically sets the value to the given updated value
 * if the current value == the expected value.
 *
 * May fail spuriously and does not provide ordering guarantees, so is
 * only rarely an appropriate alternative to compareAndSet.
 * 可能會假的失敗,並且不提供保證,因此只有少數情況下是compareAndSet的合適替代方案
 *
 * @param expect the expected value
 * @param update the new value
 * @return true if successful
 */
public final boolean weakCompareAndSet(int expect, int update) {
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}