日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Java多线程之CAS深入解析

發(fā)布時(shí)間:2024/2/28 java 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java多线程之CAS深入解析 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Java多線程之CAS深入解析


目錄:

  • CAS是什么
  • CAS底層原理Unsafe深入解析
  • CAS缺點(diǎn)

  • 引子:螞蟻花唄一面:講一講AtomicInteger,為什么要用CAS而不是synchronized?

    1. CAS是什么


  • CAS的全稱為Compare-And-Swap,它是一條CPU并發(fā)原語。

  • 它的功能是判斷內(nèi)存某個(gè)位置的值是否為期望值,如果是則更改為新的值,這個(gè)過程是原子的。

  • CAS并發(fā)原語體現(xiàn)在JAVA語言中就是sun.misc.Unsafe類中的CAS方法,JVM會(huì)幫我們實(shí)現(xiàn)CAS匯編指令。這是一種完全依賴于硬件的功能,通過它實(shí)現(xiàn)了原子操作。再次強(qiáng)調(diào),由于CAS是一種系統(tǒng)原語,原語屬于操作系統(tǒng)用語范疇范,是由若干條指令組成的,用于完成某個(gè)功能的一個(gè)過程,并且原語的執(zhí)行必須是連續(xù)的,在執(zhí)行過程中不允許被中斷,也就說CAS是一條CPU的原了指令,不會(huì)造成所謂的數(shù)據(jù)不一致問題。


  • 簡單測試代碼:

    public class CASDemo {public static void main(String[] args) {AtomicInteger atomicInteger = new AtomicInteger(5);// main do thingSystem.out.println(atomicInteger.compareAndSet(5, 6)+"current data:"+atomicInteger.get());System.out.println(atomicInteger.compareAndSet(5, 2019)+"current data:"+atomicInteger.get());} }

    編譯結(jié)果:


    2. CAS底層原理Unsafe深入解析


  • Unsafe是CAS的核心類,由于Java方法無法直接訪問底層系統(tǒng),需要通過本地(native)方法來訪問,Unsafe相當(dāng)于一個(gè)后門,基于該類可以直接操作特定內(nèi)存的數(shù)據(jù)。Unsafe類存在于sun.misc包中,其內(nèi)部方法操作可以像C的指針一樣直接操作內(nèi)存,因?yàn)镴ava中CAS操作的執(zhí)行依賴于Unsafe類的方法。

  • 注意Unsafe類中的所有方法都是native修飾的,也就是Unsafe類中的方法都直接調(diào)用操作系統(tǒng)底層資源執(zhí)行相應(yīng)任務(wù)。

  • 原子整型在i++中操作多線程環(huán)境下不需要加synchronized,也能保證線程安全,是因?yàn)樗玫氖荱nsafe類,源代碼如下:

  • 源碼解析,圖如下

    解析:getAndAddInt()方法底層調(diào)用的是unsafe,傳三個(gè)參數(shù),當(dāng)前對(duì)象,內(nèi)存地址偏移量,增量1,底層調(diào)用的是CAS思想,如果比較成功+1,失敗再重新獲得比較一次,直至成功為止。


  • 假設(shè)線程A和線程B兩個(gè)線程同時(shí)執(zhí)行g(shù)etAndAddInt操作(分別跑在不同CPU上):

  • Atomiclnteger里面的value原始值為3,即主內(nèi)存中Atomiclnteger的value為3,根據(jù)JMM模型,線程A和線程B各自持有一份值為3的value的副本分別到各自的工作內(nèi)存。

  • 線程A通過getIntVolatile(var1,var2)拿到value值3,這時(shí)線程A被掛起。

  • 線程B也通過getIntVolatile(var1,var2)方法獲取到value值3,此時(shí)剛好線程B沒有被掛起并執(zhí)行compareAndSwaplnt方法
    比較內(nèi)存值也為3,成功修改內(nèi)存值為4,線程B打完收工,一切OK

  • 這時(shí)線程A恢復(fù),執(zhí)行compareAndSwaplnt方法比較,發(fā)現(xiàn)自己手里的值數(shù)字3和主內(nèi)存的值數(shù)字4不一致,說明該值己
    經(jīng)被其它線程搶先一步修改過了,那A線程本次修改失,只能重新讀取重新來一遍了。

  • 線程A重新獲取value值,因?yàn)樽兞縱alue被volatile修飾,所以其它線程對(duì)它的修改,線程A總是能夠看到,線程A繼續(xù)執(zhí)
    行compareAndSwaplnt進(jìn)行比較替換,直到成功。


  • Unsafe底層匯編

  • 3. CAS缺點(diǎn)

    篇幅原因,新開了一個(gè)博客文章進(jìn)行解析,請(qǐng)看:

    Java基礎(chǔ)之CAS缺點(diǎn)

    總結(jié)

    以上是生活随笔為你收集整理的Java多线程之CAS深入解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。