让你了解什么是内存屏障
?
重排
內存屏障
內存屏障種類
編譯器和處理器必須同時遵守重排規則。多核處理器需使用內存屏障指令來確保一致性。即使編譯器優化掉了一個字段訪問(因為一個讀入的值未被使用),需要產生內存屏障,就像這個訪問仍然需要保護。(可參考下面的優化掉內存屏障的章節)。
內存屏障指令僅直接控制CPU與其緩存之間,與垃圾回收機制中“寫屏障(write barriers)”無關。
一、重排序
編譯器或者CPU的代碼的結構重排排序,達到最佳效果。
(1)編譯器重排
?
CPU只讀一次的x和y值。不需反復讀取寄存器來交替x和y值。
(2)處理器重排
?
?
寫緩存區沒有及時刷新,使得處理器執行的讀寫操作與內存上順序不一致。
處理器A讀b=0,處理器B讀a=0。A1寫a=1先寫到處理器A的寫緩存區中,此時內存中a=0。如果這時處理器B從內存中讀a,讀到的將是0。
可能會出現x,y都是0。
?
二、內存屏障
為了解決上述問題,處理器提供內存屏障指令(Memory Barrier):
寫內存屏障(Store Memory Barrier):處理器將存儲緩存值寫回主存(阻塞方式)。
讀內存屏障(Load Memory Barrier):處理器,處理失效隊列(阻塞方式)。
?
保證兩個操作之間數據的可見性。
volatile讀前插讀屏障,寫后加寫屏障,避免CPU重排導致的問題,實現多線程之間數據的可見性。
三、內存屏障的種類
StoreLoad開銷最大。萬能屏障,兼具其它三種內存屏障功能。執行時,處理器通常要把寫緩沖區中的數據全部刷新的內存中
?
對于處理器來說,內存屏障會導致cpu緩存的刷新,刷新時,會遵循緩存一致性協議。
lock:解鎖時,jvm會強制刷新cpu緩存,導致當前線程更改,對其他線程可見。
volatile:標記volatile的字段,在寫操作時,會強制刷新cpu緩存,標記volatile的字段,每次讀取都是直接讀內存。
final:即時編譯器在final寫操作后,會插入內存屏障,來禁止重排序,保證可見性
作者:hedgehog1112
鏈接:https://www.jianshu.com/p/08a0a8c984ab
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
總結
以上是生活随笔為你收集整理的让你了解什么是内存屏障的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么是死锁?死锁如何解决
- 下一篇: volatile超详细讲解