做廚柜有招聘網(wǎng)站嗎seo網(wǎng)站關(guān)鍵字優(yōu)化
????????Unsafe類是CAS的核心,由于Java方法無法直接訪問底層,需要通過本地方法(native)來實現(xiàn),Unsafe類相當(dāng)于一個橋梁。基于Unsafe類,可以直接操作特定的內(nèi)存數(shù)據(jù)。
? ? ? ? 我們從上一篇說CAS基本原理的時候,有說到一個“資源”被100個線程每個線程累加100次,最終得到10000,該“資源”我們使用AtomicInteger來模擬的。這篇我們就從AtomicInteger更加深入探究CAS。
? ? ? ??
AtomicInteger的getAndIncrement()方法
/*** Atomically increments by one the current value.** @return the previous value*/public final int getAndIncrement() {return unsafe.getAndAddInt(this, valueOffset, 1);}
????????AtomicInteger的getAndIncrement()方法調(diào)用的是Unsafe類中的getAndAddInt()方法,其中的參數(shù)valueOffset是通過Unsafe實例的獲取到當(dāng)前AtomicInteger這個對象的value屬性的內(nèi)存偏移地址。
Unsafe的getAndAddInt()方法
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;}
? ? ? ? 參數(shù)var1就是當(dāng)前需要Unsafe類操作的對象,在當(dāng)前案例中就是AtomicInteger的一個實例。var2則是當(dāng)前AtomicInteger實例(也就是var1)的value這個屬性的變量的內(nèi)存地址偏移量。var4就是案例中需要累加的值(案例中是1)。
? ? ? ? 接下來是一個 do{ } while()循環(huán),首先通過Unsafe類的getIntVolatile()方法(native方法)拿到當(dāng)前操作的AtomicInteger的實例中的value屬性的值,在使用Unsafe類的compareAndSwapInt()方法(native方法),將當(dāng)前操作的AtomicInteger的實例中的value屬性的原值和新值進行CAS。如果沒有交換成功就一直重復(fù)上面的動作,如果交換成功就跳出當(dāng)前循環(huán)。
? ? ??
AtomicInteger的get()方法
/*** Gets the current value.** @return the current value*/public final int get() {return value;}
? ? ? ? 等100個線程,每個都完成100次累加后(案例中使用到了CountDownLatch保證100個線程都操作完成)在調(diào)用AtomicInteger的get()方法。我們發(fā)現(xiàn)AtomicInteger的get()方法獲取的就是value這個值,value屬性是由volatile修飾的(在多線程環(huán)境下保證其可見性)。
? ? ? ? 最終我們發(fā)現(xiàn)AtomicInteger實現(xiàn)多線程并發(fā)保證線程安全,是通CAS(compare and swap)+volatile來實現(xiàn)的,從而避免synchronized的高開銷,提高執(zhí)行效率。