Atomic原子類面經(jīng)總結(jié)

首先來(lái)看看Atomic原子類的結(jié)構(gòu)

Atomic原子類的結(jié)構(gòu)

一窿凤、Automic概念

automic在java中為JUC(java.util.concurrent)并發(fā)包的一個(gè)子包夯秃。顧名思義衬潦,automic包中包含許多原子類驾锰。

1赏酥、什么是原子類?

原子是不可分割的最小單位,故原子類可認(rèn)為是其操作是不可分割的皂吮。

2、原子類的作用?

提供一種簡(jiǎn)單傲霸、性能高效、線程安全地更新一個(gè)變量的方式。


二蹈集、分析Automic底層邏輯(以AtomicInteger自增為例)

通過(guò)前面volatile的講解支示,大家應(yīng)該也對(duì)為什么要有原子類操作有了一定的了解,那我們都知道,i++自增操作不是原子性的场梆,也就是說(shuō)在高并發(fā)的情況下也許會(huì)發(fā)生重復(fù)覆蓋罐脊,這顯然不是我們想要的恃逻,那么Atomic原子類就是來(lái)解決這個(gè)問(wèn)題的,下面我們可以看來(lái)來(lái)AtomicInteger自增源碼:

AtomicInteger自增源碼

可以看到AtomicInteger的自增操作返回unsafe.getAndAddInt()方法。

這里大家可能有疑問(wèn)了甲抖,什么是unsafe呢厅篓?

對(duì)于JVM有過(guò)了解的小伙伴可能知道JNI澳盐,也就是java本地庫(kù)接口,Unsafe(sun.misc.Unsafe)是屬于JNI的類,Unsafe里面的native方法直接操作內(nèi)存扼褪,getUnfate()僅提供高級(jí)的Bootstrap類加載器使用,簡(jiǎn)而言之就是直接操作CPU砂代;

接下來(lái)查看unsafe.getAndAddInt()方法源碼

unsafe.getAndAddInt()方法源碼

可以發(fā)現(xiàn)我們?cè)赿o...while的循環(huán)條件調(diào)用了compareAndSwapInt(var1, var2, var5, var5 + var4)方法,即AtomicInteger中的CAS算法。

PS:此處對(duì)于CAS(CompareAndSwap)以及之前的volatile不熟悉的同學(xué)可以看看我的另外一篇文章叫搁,那篇文章更適合在看JUC之前了解為什么要學(xué)習(xí)JUC,思路會(huì)更清晰卧波。


三、CAS

CAS是計(jì)算機(jī)硬件對(duì)并發(fā)操作共享數(shù)據(jù)的支持望忆,CAS包含三個(gè)操作數(shù):

1、內(nèi)存值V(var1,var2)

2、預(yù)估值A(chǔ)(var 5)

3梗劫、更新值B(var5 + var4)

只有當(dāng)V==A時(shí)截碴,才會(huì)把B的值賦給V,即V=B晒旅,否則不做任何操作废恋。

不用CAS時(shí)蚓哩,線程修改數(shù)據(jù)曹阔,有從主內(nèi)存取得數(shù)據(jù)、修改數(shù)據(jù)炭序、回寫數(shù)據(jù)這三步豆茫,在回寫數(shù)據(jù)這一步侨歉,可能主內(nèi)存已經(jīng)被別的線程回寫過(guò)了,就會(huì)發(fā)生回寫覆蓋揩魂。為了解決這個(gè)幽邓,CAS在回寫的時(shí)候會(huì)將主內(nèi)存與自己工作內(nèi)存之前取得的值比較一下,就可以判斷是否已經(jīng)被別人修改過(guò)了火脉,如果沒有牵舵,我就可以修改,不過(guò)別人修改過(guò)了倦挂,我再去一次畸颅,在最新的值上面再修改。

為什么用CAS不用Synchronized呢方援?

鎖之后没炒,最耗時(shí)的就是線程的上下文交換,也就是線程被掛起和被喚醒的過(guò)程犯戏,在這個(gè)過(guò)程中送火,操作系統(tǒng)會(huì)在核態(tài)和用戶態(tài)之間切換,要保存運(yùn)行環(huán)境和恢復(fù)運(yùn)行環(huán)境先匪,這些都是很費(fèi)事的种吸,在JAVA1.6之后優(yōu)化的自旋鎖就是為了避免上下文交換。

PS:關(guān)于操作系統(tǒng)核態(tài)和用戶態(tài)是什么以及怎樣切換面試也問(wèn)的挺多的呀非,感興趣的同學(xué)可以看看我操作系統(tǒng)相關(guān)的文章和面經(jīng)坚俗。

通過(guò)上面的分析可以看到,do,while循環(huán)也避免了線程的上下文交換,性能會(huì)高很多猖败。


CAS的缺點(diǎn)

1形耗、雖然CAS沒有掛起線程、增加并發(fā)性辙浑,但是當(dāng)很多個(gè)線程進(jìn)行自旋,就會(huì)白白耗費(fèi)CPU資源拟糕,這種并發(fā)判呕,就只是讓很多線程在那循環(huán)等待。

2送滞、只能保證一個(gè)共享變量的原子操作侠草。CAS要有一個(gè)compare,一個(gè)變量就好對(duì)比犁嗅,如果是段代碼边涕,一個(gè)類呢?synchronized就能鎖這樣的褂微,當(dāng)時(shí)還有AtomicReference等類有相應(yīng)的操作功蜓。

3、ABA問(wèn)題

先有兩個(gè)線程宠蚂,其中一個(gè)運(yùn)行的比較快式撼,將主內(nèi)存中的變量從A改成了B,再?gòu)腂改成了A求厕,這個(gè)時(shí)候另外一個(gè)線程調(diào)用compareAndSwap方法時(shí)著隆,會(huì)發(fā)現(xiàn)期望值于實(shí)際值是相同的,它并不知道中間已經(jīng)被修改過(guò)了呀癣,它就會(huì)修改掉這個(gè)值美浦。

當(dāng)我們的實(shí)際問(wèn)題不能容忍這個(gè)被修改的過(guò)程,這個(gè)問(wèn)題就很嚴(yán)重了项栏,比如會(huì)員卡的問(wèn)題浦辨,用戶消費(fèi)20元,緊接著再充值20元忘嫉,如果積分統(tǒng)計(jì)線程是根據(jù)余額的減少來(lái)統(tǒng)計(jì)積分的荤牍,那就嚴(yán)重了,積分統(tǒng)計(jì)線程并不知道用戶已經(jīng)消費(fèi)過(guò)了庆冕,積分沒統(tǒng)計(jì)上康吵,這是一個(gè)大漏洞。

4访递、如何解決ABA問(wèn)題晦嵌?

在加個(gè)變量(時(shí)間戳)來(lái)表示這個(gè)變量是否被修改過(guò)了,這樣下來(lái),再執(zhí)行 compareAndSet()方法的時(shí)候惭载,不僅僅比較這個(gè)變量是否相同旱函,還要比較時(shí)間戳是否相等。

AtomicStampReference類則實(shí)現(xiàn)了這個(gè)功能

AtomicStampReference構(gòu)造函數(shù)和compareAndSet()方法

AtomicStampReference構(gòu)造函數(shù)和compareAndSet()方法

這里我們以AtomicInteger為例講解了Atomic原子類的作用描滔,通過(guò)分析AtomicInteger自增源碼我們可以知道Atomic原子類的底層是CAS棒妨,這里對(duì)于CAS也進(jìn)行了較為詳細(xì)的講解,CAS本身也是面試中經(jīng)常會(huì)遇到的問(wèn)題含长,不熟悉的同學(xué)需要進(jìn)行詳細(xì)的了解券腔。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市拘泞,隨后出現(xiàn)的幾起案子纷纫,更是在濱河造成了極大的恐慌,老刑警劉巖陪腌,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辱魁,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡诗鸭,警方通過(guò)查閱死者的電腦和手機(jī)染簇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)只泼,“玉大人剖笙,你說(shuō)我怎么就攤上這事∏氤” “怎么了弥咪?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)十绑。 經(jīng)常有香客問(wèn)我聚至,道長(zhǎng),這世上最難降的妖魔是什么本橙? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任扳躬,我火速辦了婚禮,結(jié)果婚禮上甚亭,老公的妹妹穿的比我還像新娘贷币。我一直安慰自己,他們只是感情好亏狰,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布役纹。 她就那樣靜靜地躺著,像睡著了一般暇唾。 火紅的嫁衣襯著肌膚如雪促脉。 梳的紋絲不亂的頭發(fā)上辰斋,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音瘸味,去河邊找鬼宫仗。 笑死,一個(gè)胖子當(dāng)著我的面吹牛旁仿,可吹牛的內(nèi)容都是我干的藕夫。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼枯冈,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼汁胆!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起霜幼,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎誉尖,沒想到半個(gè)月后罪既,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡铡恕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年琢感,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片探熔。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡驹针,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出诀艰,到底是詐尸還是另有隱情柬甥,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布其垄,位于F島的核電站苛蒲,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏绿满。R本人自食惡果不足惜臂外,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望喇颁。 院中可真熱鬧漏健,春花似錦、人聲如沸橘霎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)茎毁。三九已至克懊,卻和暖如春忱辅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背谭溉。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工墙懂, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人扮念。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓损搬,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親柜与。 傳聞我的和親對(duì)象是個(gè)殘疾皇子巧勤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355