資源描述:
《java并發(fā)編程(17):深入java內存模型—內存操作規(guī)則總結-編程開發(fā)技術》由會員上傳分享,免費在線閱讀,更多相關內容在工程資料-天天文庫。
1、Java并發(fā)編程(17):深入Java內存模型一內存操作規(guī)則總結-編程開發(fā)技術Java并發(fā)編程(17):深入Java內存模型一內存操作規(guī)則總結原文出處:蘭亭風雨主內存與工作內存Java內存模型的主耍目標是定義程序中各個變量的訪問規(guī)則,即在虛擬機中將變量存儲到內存和從內存中取出變量這樣的底層細節(jié)。此處的變量主要是指共享變量,存在競爭問題的變量。Java內存模型規(guī)定所有的變量都存儲在主內存屮,而每條線程還有自己的工作內存,線程的工作內存屮保存了該線程使用到的變量的主內存副木拷貝,線程對變量的所有操作(讀
2、取、賦值等)都必須在工作內存中進行,而不能直接讀寫主內存中的變量(根據Java虛擬機規(guī)范的規(guī)定,volatile變量依然有共享內存的拷貝,但是由于它特殊的操作順序性規(guī)定一一從工作內存小讀寫數據前,必須先將主內存屮的數據同步到工作內存屮,所有看起來如同直接在主內存中讀寫訪問一般,因此這里的描述對于volatile也不例外)。不同線程Z間也無法直接訪問對方工作內存中的變量,線程間變量值得傳遞均需耍通過主內存來完成。內存間交互操作Java內存模型屮定義了以下8中操作來完成主內存與工作內存Z間交互的實現細節(jié)
3、:1、luck(鎖定):作用于主內存的變量,它把一個變量標示為一條線程獨占的狀態(tài)。2、unlock(解鎖):作用于主內存的變量,它把一個處于鎖定狀態(tài)的變量釋放出來,釋放后的變量才可以被其他線程鎖定。3、read(讀取):作用于主內存的變量,它把一個變量的值從主內存?zhèn)鬏數焦ぷ鲀却驽员汶S后的load動作使用。4、load(載入):作用于工作內存的變量,它把read操作從主內存中得到的變量值放入工作內存的變量副本小。5、use(使用):作用丁作內存的變量,它把工作內存屮的一個變量的值傳遞給執(zhí)行引擎,每
4、當虛擬機遇到一個需要使用到變量的值得字節(jié)碼指令時將會執(zhí)行這個操作。6、assign(賦值):作用于工作內存的變量,它把一個從執(zhí)行引擎接收到的值賦給工作內存的變量,每當虛擬機遇到一個給變量賦值的字節(jié)碼指令時執(zhí)行這個操作。7、store(存儲):作用于工作內存的變量,它把工作內存中的一個變量的值傳遞到主內存小,以便隨后的write操作使用。8、write(寫入):作用于主內存的變量,它把store操作從工作內存中得到的變量值放入主內存的變量中。Java內存模型述規(guī)定了執(zhí)行上述8種基木操作吋必須滿足如下規(guī)
5、則:1、不允許read和load、store和write操作之一單獨出現,以上兩個操作必須按順序執(zhí)彳亍,但沒有保證必須連續(xù)執(zhí)彳亍,也就是說,read與loadZ間、store與write之間是可插入其他指令的。2、不允許一個線程丟棄它的最近的assign操作,即變量在工作內存中改變了之后必須把該變化同步回主內存。3、不允許一個線程無原因地(沒有發(fā)生過任何assign操作)把數據從線程的工作內存同步回主內存中。4、一個新的變量只能從主內存中“誕生”,不允許在工作內存中直接使用一個未被初始化(load或
6、assign)的變量,換句話說就是對一個變量實施use和store操作之前,必須先執(zhí)行過了assign和load操作。5>一個變量在同一個時刻只允許一條線程對其執(zhí)行Tock操作,但lock操作口J以被同一個條線程重復執(zhí)行多次,多次執(zhí)行l(wèi)ock后,只有執(zhí)行相同次數的unlock操作,變量才會被解鎖。6、如果對一個變量執(zhí)行l(wèi)ock操作,將會清空工作內存中此變量的值,在執(zhí)行引擎使用這個變量前,需要重新執(zhí)行l(wèi)oad或assign操作初始化變量的值。7、如果一個變量實現沒有被lock操作鎖定,則不允許對它執(zhí)行
7、unlock操作,也不允許去unlock一個被其他線程鎖定的變量。8、對一個變量執(zhí)行unlock操作Z而,必須先把此變量同步回主內存(執(zhí)行store和write操作)ovolatile型變量的特殊規(guī)則Java內存模型對volatile專門定義了一些特殊的訪問規(guī)則,當一個變量被定義成volatileZ后,他將具備兩種特性:1、保證此變量對所冇線程的可見性。這里不具體解釋了。需要注意,volatile變量的寫操作除了對它本身的讀操作可見外,volat訂e寫操作之前的所有共享變量均對volatile讀操作
8、之后的操作可見,另外注意其適用場景,詳見http://blog.csdn.net/ns_code/article/detai1s/17290021和http://blog.csdn.nct/ns_codc/articlc/dctails/17101369這兩篇博文。2、禁止指令重排序優(yōu)化。普通的變量僅僅會保證在該方法的執(zhí)行過程屮所有依賴賦值結果的地方都能獲得止確的結果,而不能保證變量賦值操作的順序與程序中的執(zhí)行順序一致,在單線程中,我們是無法感知這一點的。補%:Jav