您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關Compare And Swap的底層原理,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
概念
CAS的全稱是Compare-And-Swap,它是cpu并發原語
它的功能是判斷內存某個位置的值是否為預期值。如果是則更改為新的值,這個過程是原子的
CAS并發原語體現在java語言中就是sun.misc.Unsafe類的各個方法。調用UnSafe類中的CAS方法,JVM會幫我們實現出CAS匯編指令,這是一種完全依賴于硬件的功能,通過它實現了原子操作,再次強調,由于CAS是一種系統原語,原語屬于操作系統用于范疇,是由若干條指令組成,用于完成某個功能的一個過程,并且原語的執行必須是連續的,在執行過程中不允許被中斷,也就是說CAS是一條CPU的原子指令,不會造成所謂的數據不一致的問題,也就是說CAS是線程安全的。
代碼使用
首先使用AtomicInteger創建了一個實例,并初始化為5
// 創建一個原子類
AtomicInteger atomicInteger= new AtomicInteger(5)
然后調用CAS方法,企圖更新成2019,這里有兩個參數,一個是5,表示期望值,第二個就是我們要更新的值
atomicInteger.compareAndSet(5,2019)
然后再次使用了一個方法,同樣將值改為1024
atomicInteger.compareAndSet(5,1024)
完整代碼如下:
public class CASDemo { public static void main(String[] args) { // 創建一個原子類 AtomicInteger atomicInteger = new AtomicInteger(5); /** * 一個是期望值,一個是更新值,但期望值和原來的值相同時,才能夠更改 * 假設三秒前,我拿的是5,也就是expect為5,然后我需要更新成 2019 */ System.out.println(atomicInteger.compareAndSet(5, 2019) + "\t current data: " + atomicInteger.get()); System.out.println(atomicInteger.compareAndSet(5, 1024) + "\t current data: " + atomicInteger.get()); } }
上面代碼的執行結果為:
這是因為我們執行第一個的時候,期望值和原本值是滿足的,因此修改成功,但是第二次后,主內存的值已經改成了2019,不滿足期望值,因此返回了false,本次寫入失敗
這個就類似于SVN或者Git的版本號,如果沒有人更改過,就能夠正常提交,否者需要先將代碼pull下來,合并代碼后,然后提交
CAS底層原理
首先我們先看看atomicInteger.getAndIncrement()方法的源碼
從這里能夠看到,底層又調用了一個unsafe類的getAndAddInt方法
unsafe類
Unsafe是CAS的核心類,由于Java方法無法直接訪問底層系統,需要通過本地(Native)方法來訪問,Unsafe相當于一個后門,基于該類可以直接操作特定的內存數據,Unsafe類存在sun.misc包中,其內部方法操作可以像C指針一樣直接操作內存,因為Java中的CAS操作的執行依賴于Unsafe類的方法。
注意Unsafe類的所有方法都是native修飾的,也就是說unsafe類中的方法都直接調用操作系統底層資源執行相應的任務
為什么Atomic修飾的包裝類,能夠保證原子性,依靠的就是底層的unsafe類
變量valueOffset
表示該變量值在內存中的偏移地址,因為Unsafe就是根據內存偏移地址獲取數據的
從這里我們可以看到,通過valueOffset,直接通過內存地址,獲取到值,然后進行加1操作
變量value用volatile修飾
保證了多線程之間的內存可見性
var5:就是我們從主內存中拷貝到工作內存中的值
那么操作的時候,需要比較工作內存中的值,和主內存中的值進行比較
假設執行 compareAndSwapInt返回false,那么就一直執行 while方法,直到期望的值和真實值一樣
這里沒有用synchronized,而用CAS,這樣提高了并發性,也能夠實現一致性,是因為每個線程進來后,進入的do while循環,然后不斷的獲取內存中的值,判斷是否為最新,然后在進行更新操作。
假設線程A和線程B同時執行getAndInt操作(分別跑在不同的CPU上)
Unsafe類 + CAS思想: 也就是自旋,自我旋轉底層匯編
Unsafe類中的compareAndSwapInt是一個本地方法,該方法的實現位于unsafe.cpp中
CAS不加鎖,保證一次性,但是需要多次比較
總結CAS
CAS是compareAndSwap,比較當前工作內存中的值和主物理內存中的值,如果相同則執行規定操作,否者繼續比較直到主內存和工作內存的值一致為止
CAS應用
CAS有3個操作數,內存值V,舊的預期值A,要修改的更新值B。當且僅當預期值A和內存值V相同時,將內存值V修改為B,否者什么都不做
看完上述內容,你們對Compare And Swap的底層原理有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。