閱讀筆記--java內存模型原理

在閱讀本篇文章以前,我所理解的和上網瞭解到的java內存模型原理以下:java

不一樣架構的物理計算機能夠有不同的內存模型,Java 虛擬機也有本身的內存模型。Java 虛擬機規範中試圖定義一種 Java 內存模型(Java Memory Model,簡稱 JMM)來屏蔽掉各類硬件和操做系統的內存訪問差別,以實現讓 Java 程序在各類平臺下都能達到一致的內存訪問效果,沒必要由於不一樣平臺上的物理機的內存模型的差別,對各平臺定製化開發程序。更具體一點說,Java 內存模型提出目標在於,定義程序中各個變量的訪問規則,即在虛擬機中將變量存儲到內存和從內存中取出變量這樣的底層細節。此處的變量(Variables)與 Java 編程中所說的變量有所區別,它包括了實例字段、靜態字段和構成數值對象的元素,但不包括局部變量與方法參數,由於後者是線程私有的。與本文所寫基本相同。編程

Java 內存模型的組成緩存

 主內存架構

Java 內存模型規定了全部變量都存儲在主內存(Main Memory)中(此處的主內存與介紹物理硬件的主內存名字同樣,二者能夠互相類比,但此處僅是虛擬機內存的一部分)。學習

工做內存優化

每條線程都有本身的工做內存(Working Memory,又稱本地內存,可與前面介紹的處理器高速緩存類比),線程的工做內存中保存了該線程使用到的變量的主內存中的共享變量的副本拷貝。操作系統

工做內存是 JMM 的一個抽象概念,並不真實存在。它涵蓋了緩存,寫緩衝區,寄存器以及其餘的硬件和編譯器優化。線程

Java 內存模型抽象示意圖以下:對象

Java 內存間的交互操做blog

 

在理解 Java 內存模型的系列協議、特殊規則以前,咱們先理解 Java 中內存間的交互操做。

交互操做流程

爲了更好理解內存的交互操做,以線程通訊爲例,咱們看看具體如何進行線程間值的同步:

 

線程 1 和線程 2 都有主內存中共享變量 x 的副本,初始時,這 3 個內存中 x 的值都爲 0。

線程 1 中更新 x 的值爲 1 以後同步到線程 2 主要涉及兩個步驟:

  • 線程 1 把線程工做內存中更新過的 x 的值刷新到主內存中。

  • 線程 2 到主內存中讀取線程 1 以前已更新過的 x 變量。

 從總體上看,這兩個步驟是線程 1 在向線程 2 發消息,這個通訊過程必須通過主內存。

JMM 經過控制主內存與每一個線程本地內存之間的交互,來爲各個線程提供共享變量的可見性。

內存交互的基本操做

 

關於主內存與工做內存之間的具體交互協議,即一個變量如何從主內存拷貝到工做內存、如何從工做內存同步回主內存之類的實現細節,Java 內存模型中定義了下面 8 種操做來完成。

虛擬機實現時必須保證下面介紹的每種操做都是原子的,不可再分的(對於 double 和 long 型的變量來講,load、store、read、和 write 操做在某些平臺上容許有例外)。

8 種基本操做:

  • lock (鎖定) ,做用於主內存的變量,它把一個變量標識爲一條線程獨佔的狀態。

  • unlock (解鎖) ,做用於主內存的變量,它把一個處於鎖定狀態的變量釋放出來,釋放後的變量才能夠被其餘線程鎖定。

  • read (讀取) ,做用於主內存的變量,它把一個變量的值從主內存傳輸到線程的工做內存中,以便隨後的 load 動做使用。

  • load (載入) ,做用於工做內存的變量,它把 read 操做從主內存中獲得的變量值放入工做內存的變量副本中。

  • use (使用) ,做用於工做內存的變量,它把工做內存中一個變量的值傳遞給執行引擎,每當虛擬機遇到一個須要使用到變量的值的字節碼指令時就會執行這個操做。

  • assign (賦值) ,做用於工做內存的變量,它把一個從執行引擎接收到的值賦給工做內存的變量,每當虛擬機遇到一個給變量賦值的字節碼指令時執行這個操做。

  • store (存儲) ,做用於工做內存的變量,它把工做內存中一個變量的值傳送到主內存中,以便隨後 write 操做使用。

  • write (寫入) ,做用於主內存的變量,它把 Store 操做從工做內存中獲得的變量的值放入主內存的變量中。

總結:經過本篇文章我瞭解到了java內存模型的組成,java內存間的交互操做,8種基本操做。還有不少內容我尚未消化掉,不寫入這篇隨筆。總的來講本次閱讀,收穫頗豐,對java的理解更加深厚對之後的學習幫助很大。

相關文章
相關標籤/搜索