CAS解析

CAS:compare and swap污秆,也有的叫做 compare and set;意思都差不多墅茉,翻譯過來就是比較并交換或者比較并設(shè)值命黔。

CAS包含三個值,內(nèi)存地址(V)就斤,預(yù)期值(A)悍募,新值(B)。先比較內(nèi)存地址的值和預(yù)期的值是否相等战转,如果相等搜立,就將新值賦在內(nèi)存地址上,否則槐秧,不做任何處理啄踊。這種是樂觀鎖的思想。

CAS-1

源碼解析

CAS操作在JUC中大量用到刁标,在解析AQS那章中颠通,我們也有提到。再回頭看一下AQS中CAS的操作

protected final boolean compareAndSetState(int expect, int update) {
        return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
    }

這里是對AQS中state變量進行的CAS操作膀懈,要知道顿锰,很多同步類都是通過這個變量來實現(xiàn)線程安全的,所以在AQS中启搂,首先要保證對state的賦值是線程安全的硼控。

在java中,不論什么操作胳赌,只要他還是在Java api級別牢撼,就不能保證他一定是線程安全的,除非這個操作調(diào)用系統(tǒng)資源來支持疑苫。這里保證state線程安全是通過unsafe中的compareAndSwapInt方法來實現(xiàn)的熏版,里面的參數(shù)stateOffset就是內(nèi)存地址(V),expect是預(yù)期值(A)捍掺,新值(B)撼短。在unsafe中,大部分方法都是native的挺勿,而且unsafe可以直接操作系統(tǒng)的內(nèi)存資源曲横,不受jvm限制,通過它來保證線程安全不瓶,應(yīng)該是穩(wěn)了禾嫉,但是unsafe類官方是不建議用的,咱們平時開發(fā)大部分時候也用不著湃番,需要的操作夭织,jdk已經(jīng)幫我們封裝好了。

CAS的問題

CAS雖然看起來很完美吠撮,可以在原子級別保證一個變量的線程安全尊惰,但是它有時候也會出問題,比如著名的ABA問題泥兰。

ABA問題:我們都知道CAS操作是先比較A的預(yù)期值和內(nèi)存地址中的值是否相同弄屡,如果相同就認為此時沒有其他線程修改A值,但是一定是這樣嗎鞋诗?假如一個線程讀取到A值膀捷,此時有另外一個線程將A值改成了B,然后又將B改回了A削彬,這時比較A和預(yù)期值是相同的全庸,就認為A值沒有被改變過秀仲。為了解決ABA的問題,可以使用版本號壶笼,每次修改變量神僵,都在這個變量的版本號上加1,這樣覆劈,剛剛A->B->A保礼,雖然A的值沒變,但是它的版本號已經(jīng)變了责语,再判斷版本號就會發(fā)現(xiàn)此時的A已經(jīng)被別人偷偷改過了炮障。

CAS還有一個性能問題,在大部分使用CAS的時候坤候,都是配合自旋來使用胁赢,這里的自旋,你可以理解為for(;;)這樣的無限循環(huán)铐拐,我們在jdk源碼中找一處來看看

public final int getAndSet(int newValue) {
        for (;;) {
            int current = get();
            if (compareAndSet(current, newValue))
                return current;
        }
    }

這AtomicInteger類中g(shù)etAndSet方法徘键,這是jdk1.7中的代碼,在1.8中換成了另外一種寫法遍蟋,意思都是自旋加CAS吹害,jdk1.7中自旋在AtomicInteger里,而jdk1.8調(diào)用了unsafe中g(shù)etAndSetInt方法虚青,在這個方法中自旋它呀,有興趣的話可以去看看1.8中的源碼。

平時我們開發(fā)過程中棒厘,如果碰到系統(tǒng)蹦了纵穿,大部分人可能第一時間就會想到代碼里是不是出現(xiàn)死循環(huán)了,當(dāng)出現(xiàn)死循環(huán)時奢人,會占用系統(tǒng)大量資源谓媒,造成系統(tǒng)崩潰。在這里我們看到源碼中的自旋就是當(dāng)CAS成功時何乎,才會return句惯。當(dāng)然也不會出現(xiàn)CAS一直失敗的情況,那幾率也太小了支救。因此CAS帶來的性能問題也是需要考慮的抢野。但是從某種意思上來說,這個自旋也是CAS的優(yōu)勢各墨,自旋算是一種非阻塞算法指孤,相對于其他阻塞算法而已,非阻塞是不需要cpu切換時間片保存上下文的贬堵,節(jié)省了大量性能消耗恃轩。

結(jié)論

CAS是一種無鎖解決并發(fā)問題的手段结洼,解決了鎖引起線程切換帶來的性能問題。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末详恼,一起剝皮案震驚了整個濱河市补君,隨后出現(xiàn)的幾起案子引几,更是在濱河造成了極大的恐慌昧互,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伟桅,死亡現(xiàn)場離奇詭異敞掘,居然都是意外死亡,警方通過查閱死者的電腦和手機楣铁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門玖雁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人盖腕,你說我怎么就攤上這事赫冬。” “怎么了溃列?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵劲厌,是天一觀的道長。 經(jīng)常有香客問我听隐,道長补鼻,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任雅任,我火速辦了婚禮风范,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘沪么。我一直安慰自己硼婿,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布禽车。 她就那樣靜靜地躺著寇漫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪哭当。 梳的紋絲不亂的頭發(fā)上猪腕,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天,我揣著相機與錄音钦勘,去河邊找鬼陋葡。 笑死,一個胖子當(dāng)著我的面吹牛彻采,可吹牛的內(nèi)容都是我干的腐缤。 我是一名探鬼主播捌归,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼岭粤!你這毒婦竟也來了惜索?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤剃浇,失蹤者是張志新(化名)和其女友劉穎巾兆,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體虎囚,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡角塑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了淘讥。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片圃伶。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蒲列,靈堂內(nèi)的尸體忽然破棺而出窒朋,到底是詐尸還是另有隱情,我是刑警寧澤蝗岖,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布侥猩,位于F島的核電站,受9級特大地震影響剪侮,放射性物質(zhì)發(fā)生泄漏拭宁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一瓣俯、第九天 我趴在偏房一處隱蔽的房頂上張望杰标。 院中可真熱鬧,春花似錦彩匕、人聲如沸腔剂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽掸犬。三九已至,卻和暖如春绪爸,著一層夾襖步出監(jiān)牢的瞬間湾碎,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工奠货, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留介褥,地道東北人。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像柔滔,于是被迫代替她去往敵國和親溢陪。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348

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