Java并發(fā)之一:Java內(nèi)存模型(Memory Model)

Java內(nèi)存模型俯萎,Java Memory Model宵膨,我個人更喜歡“Java存儲模型”的譯法。

介紹

如前所述讲冠,JVM被設(shè)計成一臺抽象的虛擬計算機,JVM的并發(fā)問題及解決方案與物理計算機中的并發(fā)問題有很多相似之處适瓦。

由于現(xiàn)代計算機的內(nèi)存與CPU在運算速度上的巨大差別竿开,通常會加入一層更接近CPU讀寫速度的高速緩存(Cache),將運算使用到的數(shù)據(jù)復(fù)制到Cache中玻熙,讓運算能加速進(jìn)行否彩,運算結(jié)束后再從Cache同步回內(nèi)存之中。這個設(shè)計解決了速度的矛盾嗦随,也帶來了一個新的問題:緩存一致性列荔。在多CPU系統(tǒng)中,每個CPU都有自己的Cache枚尼,它們共享同一主內(nèi)存贴浙,當(dāng)多個CPU的運算任務(wù)涉及同一塊內(nèi)存區(qū)域時,就可能導(dǎo)致各自的Cache數(shù)據(jù)不一致署恍。對此又設(shè)計了“緩存一致性協(xié)議”崎溃,如MESI,要求各個CPU在讀寫Cache時锭汛,都遵循這些協(xié)議進(jìn)行操作笨奠,以解決緩存數(shù)據(jù)不一致的問題袭蝗。“內(nèi)存模型”(Memory Model)般婆,就是在特定的協(xié)議下到腥,對特定的高速緩存讀寫訪問過程進(jìn)行抽象。不同架構(gòu)的物理機器擁有不一樣的內(nèi)存模式蔚袍,而Java虛擬機也有自己的內(nèi)存模型乡范,其基礎(chǔ)原理是共通的。

此外啤咽,為了充分利用CPU的運算單元晋辆,可能會對輸入代碼進(jìn)行亂序執(zhí)行優(yōu)化,只保證執(zhí)行結(jié)果的一致性宇整,但不保證各語句的計算順序與輸入代碼一致瓶佳。Java虛擬機的即時編譯器也有類似的指令重排序優(yōu)化。

Java語言規(guī)范中試圖定義一種Java內(nèi)存模型鳞青,以實現(xiàn)Java程序在各種平臺上能達(dá)到一致的內(nèi)存訪問效果霸饲,為多線程的同步和避免數(shù)據(jù)爭用提供一套有效平衡高吞吐與一致性的保障機制。

什么是Java內(nèi)存模型

一個內(nèi)存模型描述的是臂拓,給定程序的某個特定的執(zhí)行軌跡(trace)是否是該程序的一個合法執(zhí)行厚脉。Java內(nèi)存模型檢查執(zhí)行軌跡中的每次讀操作,以及根據(jù)特定規(guī)則胶惰,校驗該讀操作觀察到的寫是否合法傻工。內(nèi)存模型描述了一個程序的可預(yù)期行為,具體實現(xiàn)時擁有充分的自由度去生成需要的代碼孵滞,只要其最終執(zhí)行結(jié)果可經(jīng)由內(nèi)存模型進(jìn)行推測中捆。

通俗地講,Java內(nèi)存模型(JMM)定義了一系列規(guī)則坊饶,以確保某一線程的寫操作能正確呈現(xiàn)給其他線程轨香。JMM并沒有描述多線程該如何執(zhí)行,而是描述多線程允許的行為幼东。

JMM規(guī)定了所有的共享變量都存儲在JVM的主內(nèi)存中。每條線程有自己的工作內(nèi)存科雳,用于保存該線程用到的變量的主內(nèi)存副本拷貝(具體實現(xiàn)通常不會拷貝整個對象)根蟹,線程對變量的操作全部在工作內(nèi)存中進(jìn)行,不能直接讀寫主內(nèi)存中的變量糟秘。不同的線程間也無法直接訪問對方的工作內(nèi)存简逮,線程間變量值的傳遞需要通過主內(nèi)存來完成。

關(guān)于主內(nèi)存和工作內(nèi)存之間的具體交互協(xié)議尿赚,即一個變量如何從主內(nèi)存拷貝到工作內(nèi)存散庶、如何從工作內(nèi)存同步回主內(nèi)存之類的實現(xiàn)細(xì)節(jié)蕉堰,JMM定義了8種操作(lock,unlock,read,load,use,assign,store,write),虛擬機實現(xiàn)時必須保證以上每一種操作都是原子的悲龟、不可再分的屋讶。

共享變量/堆內(nèi)存:能夠在線程間共享的內(nèi)存稱作“共享內(nèi)存或堆內(nèi)存”。所有的實例域须教、靜態(tài)域以及數(shù)組元素都存儲在堆內(nèi)存中皿渗。方法中的局部變量永遠(yuǎn)不會被線程間共享,也不會受內(nèi)存模型影響轻腺。我們也無需關(guān)心線程內(nèi)動作乐疆,每個單線程都應(yīng)遵守正確的線程內(nèi)語義。

線程間的動作:線程間的動作是由某一線程執(zhí)行贬养,能被另一線程探測或直接影響的動作挤土。包括:

共享變量的讀/寫
同步動作 (synchronization action)
? ? ? ?lock/unlock某個monitor;
? ? ? ?讀寫某個volatile變量
啟動一個線程
與外部交互的動作
導(dǎo)致某個線程進(jìn)入無限循環(huán)的動作(thread devergence action)


延伸閱讀

本文參考了《深入理解Java虛擬機》误算、《JSR-133-Memory?Model》仰美,有充裕時間的同學(xué)可以去完整過一遍,但原文有較多艱澀難懂之處尉桩。這里做了較大的裁剪筒占,隱藏更深一層的信息,以求對Java內(nèi)存模型能有一個快速又不過于淺顯的了解蜘犁。更多的概念和規(guī)則:

緩存一致性翰苫,Cache Coherence,MESI協(xié)議
Instruction Reorder这橙,指令重排序
Happens-Before?關(guān)系規(guī)則
As-If-Serial 奏窑,線程內(nèi)串行的語義
Memory Barrier,內(nèi)存屏障


參考資料:

? ? ?JSR-133 Java Memory Model
? ? 《Java語言規(guī)范SE8》第17章 線程與鎖 17.4 內(nèi)存模型
? ? 《深入理解Java虛擬機》第12章 Java內(nèi)存模型與線程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末屈扎,一起剝皮案震驚了整個濱河市埃唯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鹰晨,老刑警劉巖墨叛,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異模蜡,居然都是意外死亡漠趁,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門忍疾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來闯传,“玉大人,你說我怎么就攤上這事卤妒∩蹋” “怎么了字币?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長共缕。 經(jīng)常有香客問我洗出,道長,這世上最難降的妖魔是什么骄呼? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任共苛,我火速辦了婚禮,結(jié)果婚禮上蜓萄,老公的妹妹穿的比我還像新娘隅茎。我一直安慰自己,他們只是感情好嫉沽,可當(dāng)我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布辟犀。 她就那樣靜靜地躺著,像睡著了一般绸硕。 火紅的嫁衣襯著肌膚如雪堂竟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天玻佩,我揣著相機與錄音出嘹,去河邊找鬼。 笑死咬崔,一個胖子當(dāng)著我的面吹牛税稼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播垮斯,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼郎仆,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了兜蠕?” 一聲冷哼從身側(cè)響起扰肌,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎熊杨,沒想到半個月后曙旭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡晶府,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年夷狰,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片郊霎。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖爷绘,靈堂內(nèi)的尸體忽然破棺而出书劝,到底是詐尸還是另有隱情进倍,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布购对,位于F島的核電站猾昆,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏骡苞。R本人自食惡果不足惜垂蜗,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望解幽。 院中可真熱鬧贴见,春花似錦、人聲如沸躲株。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽霜定。三九已至档悠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間望浩,已是汗流浹背辖所。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留磨德,地道東北人缘回。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像剖张,于是被迫代替她去往敵國和親切诀。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,864評論 2 354