Java之AtomicInteger詳解

一:概念

官方文檔:

An value that may be updated atomically. An is used in applications such as atomically incremented counters, and cannot be used as a replacement for an Integer.

首先它是一個自動更新的值。其次是一種是應用於諸如自動遞增的計數器。

二:簡述和說明

在Java語言中,++i和i++操作並不是線程安全的,在使用的時候,不可避免的會用到synchronized關鍵字。而AtomicInteger則通過一種線程安全的方式進行加減操作。

三:部分源碼分析

unsafe是java提供的獲得對對象內存地址訪問的類,它的作用就是在更新操作時提供“比較並替換”(CAP)的作用。

valueOffset是用來記錄value本身在內存的編譯地址的,這個記錄,也主要是為了在更新操作在內存中找到value的位置,方便比較。

value使用了volatile關鍵字,volatile在這裡可以做到的作用是使得多個線程可以共享變量。即,保證在更新操作時,當前線程可以拿到value最新的值。

public class AtomicInteger extends Number implements java.io.Serializable { private static final long serialVersionUID = 6214790243416807050L; // setup to use Unsafe.compareAndSwapInt for updates private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final long valueOffset;

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

自動遞增核心代碼分析:

public final int incrementAndGet() {

for (;;) {

int current = get();

int next = current + 1;

if (compareAndSet(current, next))

return next;

}

}

通過源碼,可以知道,這個方法的做法為先獲取到當前的 value 屬性值,然後將 value 加 1,賦值給一個局部的 next 變量,然而,這兩步都是非線程安全的,但是內部有一個死循環,不斷去做compareAndSet操作,直到成功為止。

類似的,還有decrementAndGet()方法。它和incrementAndGet()的區別是將 value 減 1,賦值給next 變量。

AtomicInteger中還有getAndIncrement() 和getAndDecrement() 方法,他們的實現原理和上面的兩個方法完全相同,區別是返回值不同,前兩個方法返回的是改變之後的值,即next。而這兩個方法返回的是改變之前的值,即current。

四:AtomicInteger使用總結

AtomicInteger是在使用非阻塞算法實現併發控制,在一些高併發程序中非常適合,但並不能每一種場景都適合,不同場景要使用使用不同的數值類。


分享到:


相關文章: