CAS簡介
CAS的全稱為compare and swap簡單的解釋為比較交換,這個過程其實是發生在記憶體中的,應該說是組合語言的一個操作過程。
AtomicInteger
incrementAndGet()方法,將當前值加1並返回。
// AtomicInteger.java
public final int incrementAndGet() {
// getAndAddInt返回的是舊值並不是更新後的值,所以這裡返回的是舊值加1
return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}
valueoffset是AtomicInteger中被volatile關鍵字修飾的value在記憶體中的偏移量,類中的定義如下。
// AtomicInteger.java
// setup to use Unsafe.compareAndSwapInt for updates
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
private volatile int value; // 使用volatile修飾,保證獲取的都是最新值
可以看出這個偏移量在類載入過程中就得到了
// Unsafe.java
/**
* var1:物件的引用
* var2:值的偏移量
* var4:增量
*/
public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
// 這是一個native方法,拿著物件的引用以及位偏移量從記憶體中拿到值
var5 = this.getIntVolatile(var1, var2);
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));// 如果更新失敗,自旋嘗試直到成功
return var5; // 這裡返回的還是舊值
}
// 這是一個native方法
// 如果 var1 物件中 記憶體偏移量為 var2 的 value 變數的值為 var4,則更新該值為 var5
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
compareAndSwapInt傳入了四個引數:
var1:物件的引用
var2:值的偏移量
var5:期望值
var5+var4:更新值
它是一個native方法,如果更新值代替舊值成功則返回true,反則返回false
本作品採用《CC 協議》,轉載必須註明作者和本文連結