深入理解 Java 中的 CAS

Java 中的synchronized是一種悲觀鎖逗噩,悲觀鎖始終假設(shè)會(huì)發(fā)生并發(fā)沖突蝎亚,因此會(huì)阻止一切可能違反數(shù)據(jù)完整性的操作狠怨。而 CAS 是一種樂觀鎖
CAS 全稱是 Compare and Swap却妨。樂觀鎖假設(shè)不會(huì)發(fā)生并發(fā)沖突哑梳,因此只在提交的時(shí)候檢查是否違反數(shù)據(jù)完整性耻陕,如果提交失敗則會(huì)進(jìn)行重試拙徽。

CAS 支持原子更新操作,適用于計(jì)數(shù)器诗宣,序列發(fā)生器等場(chǎng)景膘怕。CAS 操作失敗時(shí)由開發(fā)者決定是繼續(xù)嘗試,還是執(zhí)行別的操作召庞。

CAS 的思想:
CAS機(jī)制當(dāng)中使用了3個(gè)基本操作數(shù):內(nèi)存地址V岛心,舊的預(yù)期值A(chǔ),要修改的新值B篮灼。

更新一個(gè)變量的時(shí)候忘古,只有當(dāng)變量的預(yù)期值A(chǔ)和內(nèi)存地址V當(dāng)中的實(shí)際值相同時(shí),才會(huì)將內(nèi)存地址V對(duì)應(yīng)的值修改為B诅诱。

public class CASCase {
    public volatile int value;

    public void add(){
        value++;
    }
}

使用javap查看編譯后的add()方法中的value++的字節(jié)碼如下:


2: getfield      #2                  // Field value:I
5: iconst_1
6: iadd
7: putfield      #2                  // Field value:I

可以看到value++被分成了三步髓堪,雖然value變量使用了volatile修飾,對(duì)value++操作禁止了指令重排序,但是value++不是原子性操作干旁,在多線程并發(fā)下還是會(huì)產(chǎn)生線程安全問題驶沼。一種解決的辦法是給add()方法加上synchronized關(guān)鍵字,但是synchronized屬于悲觀鎖争群,是否能夠進(jìn)一步提升性能呢商乎?其實(shí)還可以使用AtomicInteger來滿足我們的要求

public class CASCase {
    public AtomicInteger value;

    public void add(){
        value.getAndIncrement();
    }
}

getAndIncrement()方法底層調(diào)用的是Unsafe類的compareAndSetInt方法,用到的就是 CAS 的思想祭阀。

CAS 多數(shù)情況下對(duì)開發(fā)者來說是透明的。J.U.C 的 atomic 包提供了常用了原子性數(shù)據(jù)類型以及引用鲜戒、
數(shù)組等相關(guān)原子類型和更新操作工具专控,是很多線程安全程序的首選。Unsafe 類雖然提供 CAS 服務(wù)遏餐,但是因?yàn)槟軌虿倏v任意內(nèi)存地址讀寫而有隱患伦腐。在 Java9 之后,可以使用 Variable Handle API 來替代 Unsafe失都。

CAS 雖然很高效柏蘑,但是也有缺點(diǎn):

  • CAS 若循環(huán)時(shí)間長,則開銷很大粹庞。我們可以看到在Unsafe類的getAndAddInt()執(zhí)行時(shí)咳焚,如果 CAS 失敗,會(huì)一直循環(huán)嘗試進(jìn)行 CAS 賦值庞溜,如果長時(shí)間都在循環(huán)革半,會(huì)給 CPU 帶來很大開銷
  • CAS 只能保證一個(gè)共享變量的原子操作,但無法保證對(duì)多個(gè)共享變量的原子性操作
  • ABA 問題流码。如果一個(gè)變量在進(jìn)行 CAS 操作第一次讀取時(shí)是 A又官,中間被其他操作改成了 B,又改回了 A漫试,等到 CAS 操作第二次讀取的時(shí)候也是 A六敬,CAS 就會(huì)誤認(rèn)為這個(gè)變量從來沒有被改變過。在一些場(chǎng)景中驾荣,ABA 問題可能會(huì)影響程序的并發(fā)正確性外构。為了解決這個(gè)問題,J.U.C 提供了AtomicStampedReference秘车,可以通過變量值的版本來保證 CAS 的正確性典勇。不過在 ABA 問題下,可能用傳統(tǒng)的 加鎖互斥的方法更加高效叮趴。



    原文發(fā)表于:https://zhangxiann.com/archives/cas
    歡迎關(guān)注我的博客:zhangxiann.com
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末割笙,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌伤溉,老刑警劉巖般码,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異乱顾,居然都是意外死亡板祝,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門走净,熙熙樓的掌柜王于貴愁眉苦臉地迎上來券时,“玉大人,你說我怎么就攤上這事伏伯¢俣矗” “怎么了?”我有些...
    開封第一講書人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵说搅,是天一觀的道長炸枣。 經(jīng)常有香客問我,道長弄唧,這世上最難降的妖魔是什么适肠? 我笑而不...
    開封第一講書人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮候引,結(jié)果婚禮上侯养,老公的妹妹穿的比我還像新娘。我一直安慰自己澄干,他們只是感情好沸毁,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著傻寂,像睡著了一般息尺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上疾掰,一...
    開封第一講書人閱讀 52,475評(píng)論 1 312
  • 那天搂誉,我揣著相機(jī)與錄音,去河邊找鬼静檬。 笑死炭懊,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的拂檩。 我是一名探鬼主播侮腹,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼稻励!你這毒婦竟也來了父阻?” 一聲冷哼從身側(cè)響起愈涩,我...
    開封第一講書人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎加矛,沒想到半個(gè)月后履婉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡斟览,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年毁腿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片苛茂。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡已烤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出妓羊,到底是詐尸還是另有隱情草戈,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布侍瑟,位于F島的核電站,受9級(jí)特大地震影響丙猬,放射性物質(zhì)發(fā)生泄漏涨颜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一茧球、第九天 我趴在偏房一處隱蔽的房頂上張望庭瑰。 院中可真熱鬧,春花似錦抢埋、人聲如沸弹灭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽穷吮。三九已至,卻和暖如春饥努,著一層夾襖步出監(jiān)牢的瞬間捡鱼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來泰國打工酷愧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留驾诈,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓溶浴,卻偏偏與公主長得像乍迄,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子士败,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容