Java記憶體模型_基礎

動物園裡的一隻程式猿發表於2017-09-05

執行緒之間的通訊機制有兩種:

1、共享記憶體:執行緒之間共享程式的公共狀態,通過寫-讀記憶體中的公共狀態進行隱式的通訊。

2、訊息傳遞:執行緒之間沒有公共狀態,執行緒之間必須傳送訊息來顯示的進行通訊

同步:是指程式中用於控制不同執行緒間操作發生相對順序的機制。

在共享記憶體併發模型裡,同步是顯式進行的。程式設計師必須顯式指定某個方法或某段程式碼需要線上程之間互斥執行。在訊息傳遞的併發模型裡,由於訊息的傳送必須在訊息的接收之前,因此同步是隱式進行的。

Java的併發採用的是共享記憶體模型,Java執行緒之間的通訊總是隱式進行

 

在java中,所有例項域、靜態域和陣列元素儲存在堆記憶體中,堆記憶體線上程之間共享。區域性變數,方法定義引數和異常處理器引數不會線上程之間共享,它們不會有記憶體可見性問題,也不受記憶體模型的影響

記憶體不可見:是用於共享變數的值,沒有及時重新整理到主記憶體當中

 

Java內模型抽象結構示意圖,如下

執行緒A與執行緒B之間要通訊的話,必須要經歷下面兩個步驟。

1、首先,執行緒A把本地記憶體A中更新過的共享變數重新整理到主記憶體中去。

2、然後,執行緒B到主記憶體中去讀取執行緒A之前已更新過的共享變數。

這兩個步驟實質上是執行緒A在向執行緒B傳送訊息,而且這個通訊過程必須要經過主記憶體。JMM通過控制主記憶體與每個執行緒的本地記憶體之間的互動,來為java程式設計師提供記憶體可見性保證

 

寫緩衝區:它可以保證指令流水線持續執行,它可以避免由於處理器停頓下來等待向記憶體寫入資料而產生的延遲

處理器上的寫快取區,僅僅對它所在的處理器可見。這對記憶體操作的執行順序產生重要的影響:處理器對記憶體的讀/寫操作的執行順序,不一定與記憶體實際發生的讀/寫操作順序一致

從記憶體操作實際發生的順序來看,直到處理器A執行A3來重新整理自己的寫快取區,寫操作A1才算真正執行了。雖然處理器A執行記憶體操作的順序為:A1->A2,但記憶體操作實際發生的順序卻是:A2->A1。此時,

處理器A的記憶體操作順序被重排序了

 

為了保證記憶體可見性,java編譯器在生成指令序列的適當位置會插入記憶體屏障指令來禁止特定型別的處理器重排序。JMM把記憶體屏障指令分為下列四類:

屏障型別 指令示例 說明
LoadLoad Barriers Load1; LoadLoad; Load2 確保Load1資料的裝載,之前於Load2及所有後續裝載指令的裝載。
StoreStore Barriers Store1; StoreStore; Store2 確保Store1資料對其他處理器可見(重新整理到記憶體),之前於Store2及所有後續儲存指令的儲存。
LoadStore Barriers Load1; LoadStore; Store2 確保Load1資料裝載,之前於Store2及所有後續的儲存指令重新整理到記憶體。
StoreLoad Barriers Store1; StoreLoad; Load2 確保Store1資料對其他處理器變得可見(指重新整理到記憶體),之前於Load2及所有後續裝載指令的裝載。StoreLoad Barriers會使該屏障之前的所有記憶體訪問指令(儲存和裝載指令)完成之後,才執行該屏障之後的記憶體訪問指令。

StoreLoad Barriers是一個“全能型”的屏障,它同時具有其他三個屏障的效果。現代的多處理器大都支援該屏障(其他型別的屏障不一定被所有處理器支援)。執行該屏障開銷會很昂貴,因為當前處理器通常

要把寫緩衝區中的資料全部重新整理到記憶體中。

 

happens-before:在JMM中,如果一個操作需要對另外一個操作可見,那麼這兩個操作(可以在同一個執行緒之內,也可以不在同一個執行緒之內)之間必須要存在happens-before關係。

happens-before規則:

  • 程式順序規則:一個執行緒中的每個操作,happens- before 於該執行緒中的任意後續操作。
  • 監視器鎖規則:對一個監視器鎖的解鎖,happens- before 於隨後對這個監視器鎖的加鎖。
  • volatile變數規則:對一個volatile域的寫,happens- before 於任意後續對這個volatile域的讀。
  • 傳遞性:如果A happens- before B,且B happens- before C,那麼A happens- before C。

兩個操作之間具有happens-before關係,並不意味著前一個操作必須要在後一個操作之前執行!happens-before僅僅要求前一個操作(執行的結果)對後一個操作可見,且前一個操作按順序排在第二個操作之前。

 

有了這些基礎之後,我們在繼續往下分析

 

 

 

  

 

相關文章