一、什么是CAS
CAS的概念:CAS比較并置換,CAS是一種系統原語,原語屬于作業系統用語范疇,是由若干條指令組成的,用于完成某個功能的一個程序,并且原語的執行必須是連續的,在執行程序中不允許被中斷,也就是說CAS是一條CPU的原子指令,不會造成所謂的資料不一致問題,CAS的執行原理:CAS 操作包含三個運算元,記憶體位置(V)、預期原值(A)和新值(B),如果記憶體位置的值與預期原值相匹配,那么處理器會自動將該位置值更新為新值,否則,處理器不做任何操作,CAS 有效地說明了“我認為位置 V 應該包含值 A;如果包含該值,則將 B 放到這個位置;否則,不要更改該位置,只告訴我這個位置的值即可,”
二、JDK中的CAS
java.util.concurrent.atomic 包下的類都是基于CAS實作的

由原始碼我們可以看出JDK的CAS使用的unsafe中的方法,他的實作是本地方法,也就是說JDK的CAS采用的是CPU提供的CAS原語操作,并不是JDK自己實作的,
三、CAS的缺點
1、cpu開銷大:在高并發下,許多執行緒,更新一變數,多次更新不成功,回圈反復,給cpu帶來大量壓力,
限制回圈次數可以避免開銷,JAVA中的自旋鎖,java中的自旋鎖是一種假設在不久將來,當前的執行緒可以獲得鎖,因此虛擬機會讓當前想要獲取鎖的執行緒做幾個慷訓圈(這也是稱為自旋的原因),在經過若干次回圈后,如果得到鎖,就順利進入臨界區,如果還不能獲得鎖,那就會將執行緒在作業系統層面掛起,這種方式確實也是可以提升效率的,但問題是當執行緒越來越多競爭很激烈時,占用CPU的時間變長會導致性能急劇下降,因此Java虛擬機內部一般對于自旋鎖有一定的次數限制,可能是50或者100次回圈后就放棄,直接掛起執行緒,讓出CPU資源,
2、ABA問題:比如說一個執行緒one從記憶體位置V中取出A,這時候另一個執行緒two也從記憶體中取出A,并且two進行了一些操作變成了B,然后two又將V位置的資料變成A,這時候執行緒one進行CAS操作發現記憶體中仍然是A,然后one操作成功,雖然程式正常執行了但是記憶體位置V中的A已經不是原來的那個A了,由于ABA問題帶來的隱患,各種樂觀鎖的實作中通常都會用版本戳version來對記錄或物件標記,避免并發操作帶來的問題,在Java中,AtomicStampedReference<E>也實作了這個作用,它通過包裝[E,Integer]的元組來對物件標記版本戳stamp,從而避免ABA問題

AtomicStampedReference的建構式中需要一個初始值和一個版本號

compareAndSet()方法:置換前必須比較期望值的當前值以及期望值的版本號與當前值得版本號
- V expectedReference:期望值
- V newReference:新值
- int expectedStamp:期望版本號
- int newStamp:新值得版本號
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/281133.html
標籤:其他
上一篇:【Mybatis原始碼決議】- JDBC連接資料庫的原理和操作
下一篇:Python實作猜數字游戲
