JMM全名為Java Memory Model, 中文翻譯Java記憶體模型,一種符合記憶體模型規範的,屏蔽了各種硬體和作業系統的存取差異的,確保了Java程式在各種平台下對記憶體的存取都能保證效果一致的機制及規格。
Java記憶體模型規定了所有的變數都儲存在主記憶體中,每個執行緒還有自己的工作記憶體。
線程的工作記憶體中保存了該執行緒中是用到的變數的主記憶體副本拷貝,執行緒對變數的所有操作都必須在工作記憶體中進行,而不能直接讀寫主記憶體。
不同的執行緒之間也無法直接存取對方工作記憶體中的變量,執行緒間變數的傳遞均需要自己的工作記憶體和主記憶體之間進行資料同步進行。
而JMM作用於工作記憶體和主記憶體之間資料同步過程。他規定瞭如何做資料同步以及何時做資料同步。
#主記憶體和工作內存,可以簡單的類比成計算機記憶體模型中的主存和快取的概念。特別要注意的是,主記憶體和工作記憶體與JVM記憶體結構中的Java堆、堆疊、方法區等並不是同一個層次的記憶體劃分,無法直接類比。
如果一定要勉強對應的話,從變數、主記憶體、工作記憶體的定義來看,主記憶體主要對應於Java堆中的物件實例資料部分。工作記憶體則對應於虛擬機器棧中的部分區域。
#保證資料記憶體可見性
可見性
初始變數首先儲存在主記憶體中;
執行緒操作變數需要從主記憶體拷貝到執行緒本地記憶體中;
執行緒的本地工作記憶體是一個抽象概念,包括了快取、store buffer(後面會講到)、暫存器等。
線程A與線程B之間要通訊的話,必須經歷下面2個步驟:
線程A把本地記憶體A中更新過的共享變數刷新到主記憶體中去。
線程B到主記憶體中去讀取線程A之前已更新過的共享變數。
final(不可變) 也是可以的
使用synchronized關鍵字,在同步方法/同步區塊開始時(Monitor Enter),使用共享變數時會從主記憶體刷新變數值到工作記憶體中(即從主記憶體讀取最新值到執行緒私有的工作記憶體中),在同步方法/同步區塊結束時(Monitor Exit),會將工作記憶體中的變數值同步到主記憶體中去(即將執行緒私有的工作記憶體中的值寫入到主記憶體進行同步) .使用Lock介面的最常用的實作ReentrantLock(重入鎖)來實現可見性:當我們在方法的開始位置執行lock.lock()方法,這和synchronized開始位置(Monitor Enter)有相同的語義,即使用共享變數時會從主記憶體刷新變數值到工作記憶體中(即從主記憶體中讀取最新值到線程私有的工作記憶體中),在方法的最後finally區塊執行lock .unlock()方法,和synchronized結束位置(Monitor Exit)有相同的語意,即會將工作記憶體中的變數值同步到主記憶體中去(即將執行緒私有的工作記憶體中的值寫入到主記憶體進行同步)。 final關鍵字的可見性是指:被final修飾的變量,在建構函式數一旦初始化完成,並且在建構函式中並沒有把「this」的引用傳遞出去(「this」引用逃逸是很危險的,其他的執行緒很可能透過該引用訪問只「初始化一半」的物件),那麼其他執行緒就可以看到final變數的值。以上是Java記憶體模型有什麼作用的詳細內容。更多資訊請關注PHP中文網其他相關文章!