Java記憶體可見性
阿新 • • 發佈:2022-03-10
一、Java記憶體模型(JMM)
執行緒-》工作記憶體-》主記憶體
主記憶體
1、儲存Java例項物件
2、包括成員變數、類資訊、常量、靜態變數等
3、屬於資料共享區域,多執行緒併發操作時會引發執行緒安全
工作記憶體
1、儲存當前方法的所有本地變數資訊,本地變數對其他執行緒不可見
2、屬於對主記憶體變數的拷貝
3、位元組碼行號指示器、native方法資訊
4、屬於執行緒私有資料區域,不存線上程安全問題
Java記憶體區域劃分
主記憶體:堆和方法區
工作記憶體:程式計數器、虛擬機器棧、以及本地方法棧
儲存型別與操作方式
主記憶體:成員變數、static變數、類資訊均被儲存在主記憶體中
工作記憶體:方法裡本地變數為基本資料型別將儲存在工作記憶體的棧幀結構中;為引用型別引用儲存在工作記憶體,例項儲存在主記憶體中
二、JMM如何解決可見性問題
指令重排序
無法通過happens-before原則推到出來的,才能進行指令的重排序
A操作的結果需要對B操作可見,A與B存在happens-before關係,有八大原則
volatile(原則之一)
JVM提供的輕量級同步機制
1、保證被修飾的共享變數對所有執行緒可見
2、禁止指令的重排序優化
3、在多執行緒中運算子操作,並不保證安全性,大多數情況下可以使用synchronized來修飾執行運算的方法,它會建立記憶體屏障,保證所有CPU執行結果重新整理到主存中
為何立即可見
寫操作時,立刻將對應工作記憶體的值重新整理到主記憶體的共享變數中
讀操作時,把執行緒對應的工作記憶體置為無效,重新讀取
如何禁止重排優化
記憶體屏障(Memory Barrier)