1. 程式人生 > 其它 >Java記憶體可見性

Java記憶體可見性

一、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)