Java多線程之原子性

友情提示:作為一個java小白最近在看java多線程知識,東西還是比較多咬像,推薦大家去看《Java多線程編程指南》算撮,怕自己忘了,所以決定碼些字县昂。

開始之前肮柜,建議大家一定要系統(tǒng)地學(xué)習(xí)一下操作系統(tǒng),并且不能光看網(wǎng)上碎片化的知識點(diǎn)倒彰,所以一點(diǎn)一點(diǎn)來吧审洞。

我準(zhǔn)備先回顧一下非常基礎(chǔ)而且重要的知識點(diǎn)待讳,先從三個特性下手芒澜,原子性,可見性创淡,有序性痴晦。每一點(diǎn)的內(nèi)容都很多,一點(diǎn)一點(diǎn)來琳彩,先介紹原子性誊酌。

原子性:

書本上的定義:對于涉及共享變量訪問的操作部凑,若該操作從其執(zhí)行線程以外的任意線程來看是不可分割的,那么該操作就是原子操作碧浊,相應(yīng)的我們就稱該操作是具有原子性的涂邀。

這句話的豐富含義有:

1.原子操作是對于多線程而言的,對于單一線程箱锐,無所謂原子性比勉。有點(diǎn)多線程常識的朋友這個都應(yīng)該知道,但也要時刻牢記瑞躺。

2.原子操作是針對共享變量的敷搪。因此,涉及局部變量(如方法中的變量)我們是沒必要要求它具有原子性的幢哨,

3.原子操作是不可分割的赡勘。(我們要站在多線程的角度)指訪問某個共享變量的操作從其執(zhí)行線程之外的線程來看,該操作要么已經(jīng)執(zhí)行完畢捞镰,要么尚未發(fā)生闸与,其他線程不會看到執(zhí)行操作的中間結(jié)果。學(xué)過數(shù)據(jù)庫的朋友應(yīng)該很熟悉這種原子性岸售。那么践樱,站在訪問變量的角度,我們可以這樣看凸丸,如果要改變一個對象拷邢,而該對象包含一組需要同時改變的共享變量,那么屎慢,在一個線程開始改變一個變量之后瞭稼,在其它線程看來,這個對象的所有屬性要么都被修改腻惠,要么都沒有被修改环肘,不會看到部分修改的中間結(jié)果。(這只是最簡單的一種解釋集灌,以后我們還會講到i++以及初始化等操作)

好了悔雹,這是我們從書上定義角度出發(fā)得到?jīng)]有任何問題的定義,下面我想說說我對原子性的理解(可能有誤欣喧,歡迎指正)腌零。

首先保持原子性的重要性不言而喻,這可能是我們學(xué)多線程最直觀的感受唆阿。我們需要讓一個共享變量串行的被訪問修改莱没,不能造成不一致性。

這里先說一下互斥性酷鸦,學(xué)過操作系統(tǒng)的同學(xué)課上可能都接觸過生產(chǎn)者消費(fèi)者模型,這個模型里面的共享變量就是緩存區(qū)的大小。我們學(xué)過通過一個互斥變量+臨界區(qū)來控制兩個線程對緩存區(qū)的訪問臼隔。實(shí)現(xiàn)方式大概是:

```

int mutex = 1;

while(true){

? ? wait(mutex);

? ? critical section

? ? signal(mutex);

}

```

上面的這個偽代碼大概就是實(shí)現(xiàn)互斥訪問的機(jī)理嘹裂,wait(mutex)操作相當(dāng)于:

```

while(mutex <= 0);

mutex--;

```

wait()操作的意思就是當(dāng)互斥變量mutex<=0時,就一直阻塞在這里(不停循環(huán))摔握。若mutex>0寄狼,其實(shí)就是等于1,那么將mutex值變?yōu)?氨淌,接著執(zhí)行臨界區(qū)代碼泊愧。這就保證其他線程此時想進(jìn)入臨界區(qū)時由于得到mutex為0,就一直阻塞盛正。那么我們肯定還要想辦法把mutex變回1删咱,不然之后線程就進(jìn)入不了臨界區(qū)了。所以豪筝,大家就很容易想到signal(mutex)做的事情了:mutex++;

這里需要注意的是痰滋,我們要與多線程里面的wait(),signal()/notify()區(qū)別一下。上面講的互斥變量其實(shí)就是的原理续崖。同一時間我們只有一個線程能擁有鎖敲街,所以鎖具有的排他性。那么严望,實(shí)現(xiàn)鎖基本有兩種方法:

1.synchronized(內(nèi)部鎖)/Lock(顯示鎖)多艇。

2.CAS(Compare And Swap),這其實(shí)是鎖的底層實(shí)現(xiàn)像吻。之后再細(xì)講這兩塊峻黍。

說的有點(diǎn)多,拉回來萧豆。通過互斥變量(鎖)的特性奸披,我們可以實(shí)現(xiàn)多個線程執(zhí)行代碼到這個區(qū)域的時候必須先獲得許可,而且同一時間只有一個線程可以做到涮雷,所以咱們就實(shí)現(xiàn)了串行化阵面。

OK,到這里我們實(shí)現(xiàn)原子性就很簡單了,只需要把對一組共享變量的操作(或者對一個共享變量的多個原子操作)放進(jìn)臨界區(qū)就可以了洪鸭。這樣样刷,在執(zhí)行線程以外的其他線程看來,臨界區(qū)不管有多少操作都是原子操作览爵。

當(dāng)然了置鼻,在Java里面要實(shí)現(xiàn)這種多線程并發(fā)訪問這遠(yuǎn)遠(yuǎn)不夠的。

我還要強(qiáng)調(diào)一個很重要的東西蜓竹,如何判斷一個操作是不是原子操作呢箕母?

記住储藐,在Java語言中,long型和double型以外的任何類型的變量的寫操作都是原子操作嘶是。(不提讀操作的原因是如果所有線程都是讀操作的話钙勃,那么沒必要保持原子性。我們需要考慮的是read-modify-write和check-then-act這兩種形式)

所以對于基本類型和引用類型的寫操作(不是指初始化)都是本身具有原子性的聂喇。對于long型和double型我們可以簡單理解在32位虛擬機(jī)上辖源,我們先對變量的低32位賦值,再對高32位賦值希太,那么這樣兩個操作就不是原子操作了克饶,我們很可能讀到中間狀態(tài)。處理這種變量我們可以加一個volatile關(guān)鍵字誊辉,之后的文章我會詳述這個關(guān)鍵字矾湃。

還有一個命題:原子操作 + 原子操作 != 原子操作

這里給大家一個很簡單的判別方式芥映,也就是我們賦值語句=的右邊洲尊,(前提是=左邊是對共享變量的操作)一旦出現(xiàn)共享變量了,那么就不是原子操作了奈偏,因?yàn)檫@肯定涉及讀操作和寫操作坞嘀。最容易理解的就是i++(i=i+1)。

最后惊来,要更好得理解原子性丽涩,我們最好去理解一下java內(nèi)存模型,以及讀寫操作的過程裁蚁。這一塊很重要矢渊,大家不要忽略。

寫的第一篇文章枉证,有問題歡迎指正矮男,下一篇給大家介紹 可見性。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末室谚,一起剝皮案震驚了整個濱河市毡鉴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌秒赤,老刑警劉巖猪瞬,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異入篮,居然都是意外死亡陈瘦,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進(jìn)店門潮售,熙熙樓的掌柜王于貴愁眉苦臉地迎上來痊项,“玉大人锅风,你說我怎么就攤上這事∠呋椋” “怎么了遏弱?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長塞弊。 經(jīng)常有香客問我,道長泪姨,這世上最難降的妖魔是什么游沿? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮肮砾,結(jié)果婚禮上诀黍,老公的妹妹穿的比我還像新娘。我一直安慰自己仗处,他們只是感情好眯勾,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著婆誓,像睡著了一般吃环。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上洋幻,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天郁轻,我揣著相機(jī)與錄音,去河邊找鬼文留。 笑死好唯,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的燥翅。 我是一名探鬼主播骑篙,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼森书!你這毒婦竟也來了靶端?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤拄氯,失蹤者是張志新(化名)和其女友劉穎躲查,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體译柏,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡镣煮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了鄙麦。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片典唇。...
    茶點(diǎn)故事閱讀 40,872評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡镊折,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出介衔,到底是詐尸還是另有隱情恨胚,我是刑警寧澤,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布炎咖,位于F島的核電站赃泡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏乘盼。R本人自食惡果不足惜升熊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望绸栅。 院中可真熱鬧级野,春花似錦、人聲如沸粹胯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽风纠。三九已至况鸣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間议忽,已是汗流浹背懒闷。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留栈幸,地道東北人愤估。 一個月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像速址,于是被迫代替她去往敵國和親玩焰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,876評論 2 361

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