JAVA內存模型跟CPU緩存模型類似,是基於cpu緩存模型建立的,java線程內存模型屏蔽了底層不同計算機的區別。
JMM數據原子操作
1、read(讀取):從主內存讀取數據
2、load(載入):將主內存讀取到的數據寫入到工作內存
3、use(使用):從工作內存讀取數據使用
4、assign(賦值):將計算好的值重新賦值到工作內存中
5、store(存儲):將工作內存數據寫入主內存
6、write(寫入):將store過去的變量值賦值給主內存中的變量
7、lock(鎖入):將主內存變量加索,標誌爲線程獨享狀態
8、unlock(解鎖):將主內存變量解鎖,解鎖後其他線程可以鎖定該變量
以上線程一無法感知主內存變量的變化,所以導致一直在那裏循環,從而導致JMM緩存不一致的問題
1、總線加鎖(性能太低 read之前加鎖):cpu從主內存讀取數據到高速緩存,會在總線對這個數據進行加鎖,這樣其他cpu沒法去讀或寫這個數據,直到這個cpu使用完數據釋放鎖之後其他cpu才能讀取到該數據。
這樣方式將並行方式轉化成串行方式,這樣多核的意義就沒有了,性能太低
2、MESI緩存一致性協議(store操作加鎖,減少鎖粒度):多個cpu從主內存讀取同一個數據到各自的高速緩存,當其中某個cpu修改了緩存裏面的數據,會立馬將修改的數據同步到主內存中,其他cpu通過總線嗅探機制可以感知到數據的變化從而將自己緩存裏的數據失效
volatile緩存可見性實現原理
底層實現主要是通過彙編lock前綴指令,它hi鎖定這塊內存區域的緩存並協會到主內存
彙編lock指令會將當前處理期緩存行的數據立即寫入到主內存,這個操作同時會引起其他CPU裏緩存了該內存地址的數據無效
併發編程三大特性:原子性,可見性,有序性
volatitle保證可見性與有序性,但是不保證原子性,保證原子性需要藉助synchronized這樣的鎖機制