Java記憶體模型的抽象結構
阿新 • • 發佈:2018-12-23
在Java中,所有例項域,靜態域和陣列元素都儲存在堆記憶體中,堆記憶體線上程之間完成共享。區域性變數,方法定義引數和異常處理引數不會線上程之間共享,他們不會有記憶體可見性問題,也不會受記憶體模型的影響。
Java執行緒之間的通訊有Java記憶體模型(JMM)控制,JMM決定一個執行緒對共享變數的寫入何時對另外一個執行緒可見,從抽象的角度來看,JMM定義了執行緒和主記憶體之間的抽象關係:執行緒之間的共享變數儲存了該執行緒以讀/寫共享變數的副本。本地記憶體是JMM的一個抽象概念,並不是真實存在的。它涵蓋了快取,寫緩衝區,暫存器以及其他的硬體和編譯器優化。Java記憶體模型的抽象示意圖如下:
從上圖中看,如果執行緒A與執行緒B之間要通訊的話,必須經歷下面兩個步驟:
(1)執行緒A把本地記憶體A中更新過的共享變數重新整理到主記憶體中去
(2)執行緒B到主記憶體中去讀取A之前已經更新過的共享變數
看下面示意圖說明這兩個過程:
如上圖所示,本地記憶體A和本地記憶體B有主記憶體中的共享變數x的副本。假設初始時,這3個記憶體中的x的值都為0,。當執行緒A在執行時,把更新後的x的值(假設是1)臨時存放在自己的本地快取A中。當執行緒A和執行緒B需要通訊時,執行緒A首先會把自己本地記憶體中修改後的值重新整理到主記憶體中,此時主記憶體的x變成1.隨後,執行緒B到主記憶體中去讀取執行緒A更新過後的x值,此時執行緒B的本地記憶體的x為1.
從整體上看,這兩個步驟實質上是執行緒A在向執行緒B傳送訊息,而且這個通訊過程必須要經過主記憶體。JMM通過控制主記憶體與內一個執行緒的本地記憶體之間的互動,來為Java程式設計師提供記憶體可見性保證。