Java內(nèi)存模型先行發(fā)生原則

聲明:本章內(nèi)容摘自《深入理解Java虛擬機》第二版病苗,有需要深入學(xué)習(xí)的小伙伴請自行購買書籍蚣抗。



????????Java語言中有一個“先行發(fā)生”(happens-before)的原則辛臊,這個原則非常重要敏储,它是判斷數(shù)據(jù)是否存在競爭寡痰,線程是否安全的主要依據(jù)觉鼻,依靠這個原則俊扭,我們可以通過幾條規(guī)則一攬子地解決并發(fā)環(huán)境下兩個操作之間是否可能存在沖突的所有問題。

? ? ? ? 先行發(fā)生是Java內(nèi)存模型中定義的兩項操作之間的偏序關(guān)系坠陈,如果說操作A先行發(fā)生于操作B萨惑,其實就是說發(fā)生操作B之前,操作A產(chǎn)生的影響能被操作B觀察到仇矾,“影響”包括修改了內(nèi)存中共享變量的值庸蔼,發(fā)送了消息,調(diào)用了方法等贮匕。

先行發(fā)生原則偽代碼示例:

// 以下操作在線程A中執(zhí)行

i = 1姐仅;

// 以下操作在線程B中執(zhí)行

j = i;

// 以下操作在線程C中執(zhí)行

i = 2;

????????假設(shè)線程A中的操作"i=1"先行發(fā)生于線程B的操作“j=1”,那么可以確定在線程B的操作執(zhí)行后刻盐,變量j一定等于1掏膏,得出這個結(jié)論的依據(jù)有兩個:一是根據(jù)先行發(fā)生原則,i=1的結(jié)果可以被觀察到敦锌,二是線程c還沒有登場憋肖,線程A操作結(jié)束之后沒有其他線程回修改變量i的值。現(xiàn)在再來考慮線程C损拢,我們依然保持線程A和線程B之間的先行發(fā)生關(guān)系,而線程C出現(xiàn)在線程A和線程B的操作之間溺蕉,但是線程C與線程B沒有先行發(fā)生關(guān)系,那j的值回是多少呢悼做?答案不確定疯特,1和2都有可能,因為線程C對變量i的影響可能會被線程B觀察到肛走,也可能不會漓雅,這時候線程B就存在讀取到過期數(shù)據(jù)的風(fēng)險,不具備多線程的安全性朽色。

? ? ? ? 下面是Java內(nèi)存模型下一些“天然的”先行發(fā)生關(guān)系邻吞,這些先行發(fā)生關(guān)系無需任何同步器協(xié)助就已經(jīng)存在,可以在編碼中直接使用葫男,若兩個操作之間的關(guān)系不在此列抱冷,并且無法從下列規(guī)則推導(dǎo)出來的話,它們就沒有順序性保障梢褐,虛擬機就可以對它們隨意地進行重排序旺遮。

? ? ? ? ??程序次序規(guī)則(Program Order Rule):在一個線程內(nèi),按照程序代碼順序盈咳,書寫在前面的操作先行發(fā)生與書寫在后面的操作耿眉。準(zhǔn)確的說,應(yīng)該是控制流順序而不是程序代碼順序鱼响,因為要考慮分支鸣剪,循環(huán)等結(jié)構(gòu)。

??????????管程鎖定規(guī)則(Monitor Lock Rule):一個unlock操作先行發(fā)生于后面對同一個鎖的lock操作丈积。這里必須強調(diào)的是同一個鎖筐骇,而后面是指時間上的先后順序

??????????volatile變量規(guī)則(Volatile Variable Rule):對一個volatile變量的寫操作先行發(fā)生于后面對這個變量的讀操作,這里的后面同樣是指時間上的先后順序

??????????線程啟動規(guī)則(Thread Start Rule):Thead對象的start()方法先行發(fā)生于此線程的每一個動作

??????????線程終止規(guī)則(Thread Termination Rule):線程中的所有操作都先行發(fā)生于對此線程的終止檢測桶癣,我們可以通過Thread.join()方法結(jié)束拥褂,Thread.isAlive()的返回值等手段檢測到線程已經(jīng)終止執(zhí)行。

???????????線程中斷規(guī)則(Thread Interruption Rule):對線程interrupt()方法的調(diào)用優(yōu)先發(fā)生于被中斷線程的代碼檢測到中斷事件的發(fā)生牙寞,可以通過Thread.interrupted()方法檢測到是否有中斷發(fā)生饺鹃。

???????????對象終結(jié)規(guī)則(Finalizer Rule):一個對象的初始化完成(構(gòu)造函數(shù)執(zhí)行結(jié)束)先行發(fā)生于它的finalize()方法的開始。

??????????傳遞性(Transitivity):如果操作A先行發(fā)生于操作B间雀,操作B先行發(fā)生于操作C悔详,那就可以得出操作A先行發(fā)生于操作C的結(jié)論。? ? ? ??

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末惹挟,一起剝皮案震驚了整個濱河市茄螃,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌连锯,老刑警劉巖归苍,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件用狱,死亡現(xiàn)場離奇詭異,居然都是意外死亡拼弃,警方通過查閱死者的電腦和手機夏伊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吻氧,“玉大人溺忧,你說我怎么就攤上這事《⑺铮” “怎么了鲁森?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長振惰。 經(jīng)常有香客問我歌溉,道長,這世上最難降的妖魔是什么报账? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任研底,我火速辦了婚禮埠偿,結(jié)果婚禮上透罢,老公的妹妹穿的比我還像新娘。我一直安慰自己冠蒋,他們只是感情好羽圃,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著抖剿,像睡著了一般朽寞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上斩郎,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天脑融,我揣著相機與錄音,去河邊找鬼缩宜。 笑死肘迎,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的锻煌。 我是一名探鬼主播妓布,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼宋梧!你這毒婦竟也來了匣沼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤捂龄,失蹤者是張志新(化名)和其女友劉穎释涛,沒想到半個月后加叁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡唇撬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年殉农,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片局荚。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡超凳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出耀态,到底是詐尸還是另有隱情轮傍,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布首装,位于F島的核電站创夜,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏仙逻。R本人自食惡果不足惜驰吓,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望系奉。 院中可真熱鬧檬贰,春花似錦、人聲如沸缺亮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽萌踱。三九已至葵礼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間并鸵,已是汗流浹背鸳粉。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留园担,地道東北人届谈。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像粉铐,于是被迫代替她去往敵國和親疼约。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355