CAS

cas是無鎖優(yōu)化,或者叫自旋。通過Atomic類來實(shí)現(xiàn)。

由于一些常見的操作,加鎖的情況特別多,所以java提供了這些類,內(nèi)部自帶了鎖,當(dāng)然這些鎖不是由synchronized來實(shí)現(xiàn)的,而是通過cas的操作實(shí)現(xiàn)的。

public class study04 {

????public static void main(String[] args) {

????????study04 study =new study04();

? ? ? ? List threads =new ArrayList<>();

? ? ? ? for (int i=0; i <10; i++){

????????????threads.add(new Thread(study :: m, "thread-"+i));

? ? ? ? }

????????threads.forEach(o -> o.start());

? ? ? ? threads.forEach(o -> {

????????????try {

????????????????o.join();

? ? ? ? ? ? }catch (InterruptedException e) {

????????????????e.printStackTrace();

? ? ? ? ? ? }

????????});

? ? ? ? System.out.println(study.count);

? ? }

????AtomicIntegercount =new AtomicInteger(0);

? ? void m(){

????????for (int i =0; i <10000; i ++){

????????count.incrementAndGet();

? ? ????}

????}

}

count.incrementAndGet()的內(nèi)部實(shí)現(xiàn):

public final int incrementAndGet() {

????return unsafe.getAndAddInt(this, valueOffset, 1) +1;

}

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;

}

compareAndSwapInt:

cas(V, Expected, NewValue)

? ? if V == Expected

? ? ? ? V = NewValue

? ? ? ? otherwise try again or fail

V是要修改的值,Expected是期望值,NewValue是新值,如果要修改的值等于期望值,那么代表沒有其他線程修改過它,可以設(shè)定新值,否則代表有其他線程修改過值,那么cas要重新嘗試讀取期望值。cas操作是cpu原語級的,中間不允許被打斷,是原子性的。

CAS修改的如果是對象會(huì)導(dǎo)致ABA問題。線程A發(fā)現(xiàn)對象(Expected)的引用還是原來的引用,就允許修改,但其實(shí)該對象可能已經(jīng)被線程B修改過值并重新引用到原來的對象上,線程A無法發(fā)現(xiàn)。要解決ABA問題需要引入版本號,compare的時(shí)候連版本號一起比較。

CAS是通過Unsafe這個(gè)類來實(shí)現(xiàn)的。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容