Java記憶體模型的基礎

眾合網1143561141發表於2020-12-19

之前我提出過一個這麼的概念來簡化大家對執行緒的理解:

無論我們在編碼層做多麼複雜的業務處理,對於計算機而言就只有三個工作要做:

  1. 在記憶體中讀取資料
  2. CPU運算資料
  3. 將運算結果寫回記憶體

一個執行緒任務在計算機的底層中實際上完成的任務只有上面這三種,我們可以透過一個簡單計算機模型來描述上面的關係:
在這裡插入圖片描述

這裡我們的執行緒負責去主記憶體中獲取資料然後交給CPU處理,在CPU處理結束後又將資料送還給主記憶體。那麼在這個過程中,JMM(JAVA Memory Model 譯:JAVA記憶體模型)是如何設計執行緒的記憶體模型來實現資料搬運處理的能力呢?這裡我們可以看下面的這個JMM基礎記憶體模型:

在這裡插入圖片描述

這裡如果執行緒A想要完成 i=1 的這個賦值操作,就需要經歷下面的這個過程:

  1. 執行緒A在主記憶體中讀取 int  i,將int i複製一份儲存到執行緒A的私有記憶體空間
  2. 執行緒A將一個新的值0賦予 i ,然後將更新後的i寫回到記憶體中

雖然上面的流程看起來很簡單,但是如果在併發的情況下是會存在問題的:

  1. 執行緒A 在主記憶體中讀取 int  i,將int i複製一份儲存到執行緒A的私有記憶體空間
  2. 執行緒B 想要執行 i = i+1 的指令,此時執行緒A還沒有還沒有將更新後的值寫回主記憶體
  3. 執行緒B 讀到 int i = 0 並將讀到的共享變數複製寫入自己的私有記憶體空間
  4. 執行緒A 完成 i=1 的賦值並將結果寫回到主記憶體
  5. 執行緒B 此時拿到自己私有記憶體變數 i=0 來計算 i=i+1 並得到結果1
  6. 執行緒B 將得到的結果寫回主記憶體

我們期望的運算結果應該是i=2 ,但是由於執行緒B沒有及時能夠讀到執行緒A更新的變數值,所以出現了我們讀到i=1的結果,這無疑是執行緒不安全的。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69979681/viewspace-2743637/,如需轉載,請註明出處,否則將追究法律責任。

相關文章