java 內(nèi)存模型 volatile 語義

本文參考 《深入理解JAVA虛擬機(jī)》(周志明) 第二版,p362 万俗,對(duì)文中內(nèi)容提煉加以總結(jié)而成璃吧。

  • java內(nèi)存模型的產(chǎn)生,是為了解決各個(gè)硬件和操作系統(tǒng)對(duì)內(nèi)存訪問的差異俯树。
  • 主要針對(duì)變量來定義各種規(guī)則帘腹,線程私有變量不算,因?yàn)椴淮嬖诰€程安全問題
  • “二八原則”许饿,二指兩個(gè)內(nèi)存阳欲,線程工作內(nèi)存、 主內(nèi)存陋率。線程工作內(nèi)存無法直接訪問(讀寫)主內(nèi)存球化,每個(gè)線程的線程工作內(nèi)存也無法直接互相訪問。這兩個(gè)內(nèi)存的交互有具體協(xié)議瓦糟,即八個(gè)原子操作
  • lock: 作用于主內(nèi)存筒愚,把一個(gè)變量表示為一條線程獨(dú)占
    unlock: 作用于主內(nèi)存,把一個(gè)處于鎖定的變量釋放狸页,釋放后才可以被其他線程鎖定
    read:作用于主內(nèi)存的變量锨能,把主內(nèi)存變量值傳入工作內(nèi)存,方便后面 load
    load:作用于工作內(nèi)存芍耘,將read讀取的值載入工作內(nèi)存副本
    use:作用于工作哦內(nèi)存址遇,把工作內(nèi)存的某個(gè)值傳給執(zhí)行引擎,虛擬機(jī)每次使用變量值則調(diào)用這個(gè)
    assign:作用于工作內(nèi)存的變量斋竞,把一個(gè)從執(zhí)行引擎接收到的值復(fù)制給工作內(nèi)存的變量倔约,虛擬機(jī)每次給變量復(fù)制使用這個(gè)
    store:作用于工作內(nèi)存的變量,把工作內(nèi)存值傳給主內(nèi)存 (類比read)
    write:作用于主內(nèi)存的變量坝初,把store操作從工作內(nèi)存中得到的變量的值放入主內(nèi)存中(類比load)

這8個(gè)原子操作的一些規(guī)定 和 后面 volatile的某些特殊約定浸剩,共同決定了java線程安全體系钾军。

1. (read load) (store write) 這兩組操作必須按順序執(zhí)行
2. (read load) (store write)這兩組操作必須完整,不能只出現(xiàn)read 沒有l(wèi)oad 類似這種
3.  如果執(zhí)行了 assign绢要, 則后續(xù)必須有 store write
4.  不允許無原因的(沒發(fā)生過 assign)吏恭,就發(fā)生 store write
5.  新變量只能在主內(nèi)存中誕生
6. lock可以被一個(gè)線程執(zhí)行多次,但unlock需要相同的次數(shù)
7. lock會(huì)清空工作內(nèi)存中此變量的值重罪,在執(zhí)行引擎使用這個(gè)變量前樱哼,需要重新執(zhí)行 load 或 assign
8. 沒有l(wèi)ock 不可 unlock
9. unlock之前 ,必須對(duì)該變量 store write

synchronized 隱式的使用lock和unlock剿配,對(duì)于7和9來說搅幅,可以保證線程間變量的可見性
可見性:一個(gè)線程修改了這個(gè)變量的值,其他線程可以立即知道

volatile規(guī)則:
volatile能保證變量在線程之間的可見性
volatile修飾的變量具有的可見性呼胚,用8個(gè)原子操作解釋為: use之前茄唐,必須 read+load,assign之后蝇更,必須 store+write
volatile能禁止指令重排序優(yōu)化
重排序優(yōu)化是機(jī)器級(jí)的優(yōu)化操作沪编,用代碼形象解釋如下:

volatile boolean initialized = false;
//thread A
loadConfig();
initialized = true;

//thread B
while(!initialized){
  sleep();
}
doNext();

這代碼意思就是 線程A先 loadConfig(),然后 initialized 為 true,線程B再去進(jìn)行下面工作年扩。如果進(jìn)行重排序優(yōu)化漾抬,則可能先在A線程 先執(zhí)行 initiallized = true,后執(zhí)行l(wèi)oadConfig()常遂,導(dǎo)致B在 A線程 loadConfig() 之前跳出 while循環(huán),顯然不對(duì)挽荠。
volatile如何禁止重排序的呢克胳,使用內(nèi)存屏障。其實(shí)重排序優(yōu)化是有條件的圈匆,必須前后無依賴漠另,比如 :

A = A+10
A *= 2

類似這里(舉個(gè)栗子,不代表任意代碼) 兩個(gè)語句前后依賴跃赚,就不能重排序笆搓。所謂的內(nèi)存屏障,就是刻意制造這種依賴纬傲,致使代碼不能重排序满败。(具體操作 lock addl $0x0,(%esp)壁酬,把ESP寄存器的值加0找爱,顯然是一個(gè)空操作,相當(dāng)于做了一次 store + write徘意,只不過啥也沒改汁雷,但是你不能越過這個(gè)操作去執(zhí)行下面的操作
從8個(gè)原子操作理解的話净嘀,即為:

T表示線程报咳,所以這里在同一個(gè)線程內(nèi)
A B 表示操作
V W 表示volatile變量
A1:T->V   use | assign
A2:T->V   load | store
A3:T->V   read | write

B1:T->W   use | assign
B2:T->W   load | store
B3:T->W   read | write

A1先于B1  =>  A3先于B3
========
個(gè)人理解:
V = 1; (執(zhí)行了 A1,A2挖藏,A3)
W = 2暑刃;(執(zhí)行了 B1,B2膜眠,B3)
從代碼上來看岩臣,A3 先于 B3,由于不能重排序 所以 A1 一定先于 B1
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末柴底,一起剝皮案震驚了整個(gè)濱河市婿脸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌柄驻,老刑警劉巖狐树,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異鸿脓,居然都是意外死亡抑钟,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門野哭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來在塔,“玉大人,你說我怎么就攤上這事拨黔』桌#” “怎么了?”我有些...
    開封第一講書人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵篱蝇,是天一觀的道長(zhǎng)贺待。 經(jīng)常有香客問我,道長(zhǎng)零截,這世上最難降的妖魔是什么麸塞? 我笑而不...
    開封第一講書人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮涧衙,結(jié)果婚禮上哪工,老公的妹妹穿的比我還像新娘。我一直安慰自己弧哎,他們只是感情好雁比,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著撤嫩,像睡著了一般章贞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,208評(píng)論 1 299
  • 那天鸭限,我揣著相機(jī)與錄音蜕径,去河邊找鬼。 笑死败京,一個(gè)胖子當(dāng)著我的面吹牛兜喻,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播赡麦,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼朴皆,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了泛粹?” 一聲冷哼從身側(cè)響起遂铡,我...
    開封第一講書人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎晶姊,沒想到半個(gè)月后扒接,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡们衙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年钾怔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蒙挑。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡宗侦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出忆蚀,到底是詐尸還是另有隱情矾利,我是刑警寧澤,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布馋袜,位于F島的核電站梦皮,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏桃焕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一捧毛、第九天 我趴在偏房一處隱蔽的房頂上張望观堂。 院中可真熱鬧,春花似錦呀忧、人聲如沸师痕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽胰坟。三九已至,卻和暖如春泞辐,著一層夾襖步出監(jiān)牢的瞬間笔横,已是汗流浹背竞滓。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留吹缔,地道東北人商佑。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像厢塘,于是被迫代替她去往敵國和親茶没。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354