Java內存模型的主要目標是定義程序中各個變量的訪問規則,即在虛擬機中將變量存儲到內存和從內存中取出變量這樣的底層細節。此處的變量(Variable)與Java編程中所說的變量略有區別,它包括了實例字段、靜態字段和構成數組對象的元素,可是不包括局部變量與方法參數,由於後者是線程私有的,不會被共享,天然就不存在競爭問題。爲了得到較好的執行效能,Java內存模型並無限制執行引擎使用處理器的特定寄存器或緩存來和主內存進行交互,也沒有限制即時編譯器調整代碼執行順序這類權利。java
Java內存模型規定了全部的變量都存儲在主內存(MainMemory)中(此處的主內存與介紹物理硬件時的主內存名字同樣,二者也能夠互相類比,但此處僅是虛擬機內存的一部分)。每條線程還有本身的工做內存(WorkingMemory,可與前面所講的處理器高速緩存類比),線程的工做內存中保存了被該線程使用到的變量的主內存副本拷貝,線程對變量的全部操做(讀取、賦值等)都必須在工做內存中進行,而不能直接讀寫主內存中的變量。不一樣的線程之間也沒法直接訪問對方工做內存中的變量,線程間變量值的傳遞均須要經過主內存來完成,線程、主內存、工做內存三者的交互關係以下圖所示。編程
圖 1 線程、主內存、工做內存三者的交互關係數組
這裏所講的主內存、工做內存與本書第2章所講的Java內存區域中的Java堆、棧、方法區等並非同一個層次的內存劃分。若是二者必定要勉強對應起來,那從變量、主內存、工做內存的定義來看,主內存主要對應於Java堆中對象的實例數據部分[5],而工做內存則對應於虛擬機棧中的部分區域。從更低的層次來講,主內存就是硬件的內存,而爲了獲取更好的運行速度,虛擬機及硬件系統可能會讓工做內存優先存儲於寄存器和高速緩存中。緩存
關於主內存與工做內存之間具體的交互協議,即一個變量如何從主內存拷貝到工做內存、如何從工做內存同步回主內存之類的實現細節,Java內存模型中定義瞭如下八種操做來完成:線程
若是要把一個變量從主內存複製到工做內存,那就要按順序地執行read和load操做,若是要把變量從工做內存同步回主內存,就要按順序地執行store和write操做。注意,Java內存模型只要求上述兩個操做必須按順序執行,而沒有保證必須是連續執行。也就是說read與load之間、store與write之間是可插入其餘指令的,如對主內存中的變量a、b進行訪問時,一種可能出現的順序是reada、readb、loadb、loada。除此以外,Java內存模型還規定了在執行上述八種基本操做時必須知足以下規則:對象
周志明:<深刻理解Java虛擬機>blog
深刻理解Java內存模型(一)——基礎:http://www.infoq.com/cn/articles/java-memory-model-1內存