在JDK1.5開始,AtomicInteger中就基於CAS原理做了相關操作。
public static void main(String[] args) throws Exception{
//初識值爲0
AtomicInteger atomicInteger = new AtomicInteger();
//查看當前對象的值
System.out.println("初始值:"+atomicInteger.get());
//給對象當前值加1並返回該值
atomicInteger.incrementAndGet();
//查看當前對象的值
System.out.println("當前值:"+atomicInteger.get());
}
運行結果:
點擊incrementAndGet()進去查看
我們先查看方法中如何定義unsafe、valueOffset這兩個變量
private static final long valueOffset;
static {
try {
//獲取值value在這個對象內存中的起始位置
//對象可以具象理解爲jvm中的一段內存,對象中的屬性信息在這段內存中都是有序排列的,該方法呢就是獲取value在這段內存中的起始位置
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
現在查看 incrementAndGet()的具體實現
/**
* var1:當前對象
* var2:對象中value在對象內存中的起始位置
* var4:固定值 1
**/
public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
//獲取當前對象的value值
var5 = this.getIntVolatile(var1, var2);
//比較獲取的值var5和對象現在的值是否相同(防止當前該值已經被其他線程修改)
//不同==>繼續獲取對象的最新value然後進行比較(自旋)
//相同==>將對象的value改成var5 + var4(對象的值+1),並返回剛纔獲取的var5
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
return var5;
}
進一步查看一眼compareAndSwapInt(Object var1, long var2, int var4, int var5)
在返回看AtomicInteger.incrementAndGet()的方法
/**
* Atomically increments by one the current value.
*
* @return the updated value
*/
public final int incrementAndGet() {
//unsafe.getAndAddInt(this, valueOffset, 1):獲取對象當前的值
return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}
以上是JDK1.5後java對CAS使用的一個基礎案例
compareAndSwapInt(Object var1, long var2, int var4, int var5)由於是用native修飾的暫時沒有進一步追蹤,後查閱資料瞭解到其底部是通過已經彙編指令執行的 ==> lock cmpxchg 指令
//在實際讓對象的值改變前判斷系統是否是多核的
//是 ==》 指令前添加lock(鎖)執行
//不是==》直接執行指令
lock cmpxchg 指令
//cmpxchg = cas修改變量值