深入理解java虛擬機--第12章:
1.JMM主要用來屏蔽掉各種硬件與操作系統(tǒng)的內(nèi)存訪問差異尤筐,以實現(xiàn)讓Java程序在各種平臺下都能達到一致的內(nèi)存訪問效果恰矩。(平臺無關性)
2.其主要目標定義程序中各個變量的訪問規(guī)則熟尉,即在虛擬機中將變量存儲到內(nèi)存和從內(nèi)存中去除變量的底層細節(jié)鸽凶。此處變量和java編程時的變量有所區(qū)別(主要指那些可以共享的變量但绕,在堆、方法區(qū)之類的锭部;像那些存儲在棧里的就不在考慮之內(nèi)):其包括 -> 實例字段、靜態(tài)字段和構成數(shù)組對象的元素耻台,但不包括局部變量與方法參數(shù)空免。
3.JMM分住內(nèi)存與工作內(nèi)存,前者被規(guī)定存儲所有變量盆耽;而后者負責對變量的所有操作(讀取蹋砚、賦值等),由于其不能直接讀取住內(nèi)存中的變量摄杂,因此會只是保存用到變量的主內(nèi)存副本拷貝用于變量操作坝咐。
4.那么住內(nèi)存與工作內(nèi)存如何交互呢?JMM定義了8種原子的析恢、不可再分的操作來保證:lock,unlock,read,load,use,assign,store,write(其中l(wèi)ock,unlock,read,write作用于主內(nèi)存墨坚;load,use,assign,store作用于工作內(nèi)存),其中read與load映挂、store與write必須順序但不一定連續(xù)執(zhí)行泽篮;(這也是保證內(nèi)存一致性吧?)并且為了保證并發(fā)的安全性柑船,這8種操作還必須遵循一些規(guī)則:1).不允許read與load帽撑、store與write操作之一單獨出現(xiàn);2).assign操作若被執(zhí)行就不能丟棄鞍时,若沒被執(zhí)行就不能同步到主內(nèi)存【這點我理解與后一點呼應了】亏拉;3).新變量只能在主內(nèi)存誕生,就是實施use逆巍、store之前及塘,必須執(zhí)行過assign、load锐极。4).lock只發(fā)生在一個變量笙僚、一個時刻、一條線程溪烤,并且lock與unlock數(shù)量一致味咳,unlock之前得有l(wèi)ock,不允許unlock其他線程變量檬嘀。5).lock一個變量會清空工作內(nèi)存中此變量的值槽驶,因此回去執(zhí)行l(wèi)oad或assign操作初始化變量值;unlock一個變量之前鸳兽,會同步此變量到主內(nèi)存中掂铐,即執(zhí)行store、write操作。還有對volatile的一些特殊規(guī)定全陨。
5.volatile具有兩種特性:1).保證此變量對所有線程可見(在各個線程的工作內(nèi)存中爆班,volatile變量也可以存在不一致的情況,但由于每次使用之前都要先刷新辱姨,執(zhí)行引擎看不到不一致的情況柿菩,因此認為不存在一致性的問題);2).禁止指令重排序優(yōu)化(機器級的雨涛,對應的匯編代碼)枢舶。如何禁止?修改某個變量后替久,多執(zhí)行了一行l(wèi)ock前綴的操作(它把修改同步到內(nèi)存凉泄,意味著所有之前的操作都已經(jīng)執(zhí)行完成,起到了“指令重排序無法越過內(nèi)存屏障”的效果)后众,相當于一個內(nèi)存屏障,其作用使得本CPU的cache寫入內(nèi)存颅拦,從而引起別的CPU或內(nèi)核無效化其cache蒂誉,類似JVM中的“store和write”操作。這時再看JVM對volatile變量的特殊規(guī)則--load距帅、read拗盒、use必須連續(xù)一起出現(xiàn)(保證自己看到最新值);assign锥债、store、write必須連續(xù)一起出現(xiàn)(保證其它線程看到最新值)痊臭;還有一條(P372)是不同變量的use或者assign操作決定load或store哮肚、read或write的順序(保證代碼的執(zhí)行順序與程序的順序相同)。
6.先行發(fā)生原則广匙,是JVM定義的兩項操作之間的偏序關系允趟。程序次序規(guī)則;管程鎖定原則鸦致;volatile變量原則潮剪;線程啟動原則;線程終止原則分唾;線程中斷原則抗碰;對象終結原則;傳遞性绽乔。