1 保證可見性:
記憶體可見性是指乙個cpu對資料修改,對其他cpu立即可見。
(1)」cpu對資料修改「:
cpu對資料的修改總是先修改工作記憶體,然後再同步回主記憶體,只不過是對被volatile修飾變數的修改,會立刻同步回主記憶體。
(2)」對其他cpu立即可見「:
當cpu_a修改完volatile變數,並且立即同步回主存,如果cpu_b的工作記憶體中也快取了這個變數,那麼b的這個變數將立即失效,當b想要修改這個變數的時候,b必須從主存重新獲取變數的值。
實現原理:
基於cpu的mesi協議(快取一致性協議),其中m表示modify,e表示獨佔exclusive,s表示shared,i表示invalid。如果乙個cpu修改了資料,那麼這個cpu的資料狀態就會更新成m,同時其他cpu上的資料狀態更新成i,這個是通過cpu多核之間的嗅探機制實現的。
2 防止重排序:
實現原理:
記憶體屏障(memory barrier),像一套柵欄分割前後的**,阻止柵欄前後的沒有資料依賴性的**進行指令重排序,保證程式在一定程度上的有序性。
在單例模式中,instance inst = new instance(); 這一句**不是原子操作,它可以分成三步原子指令:
(1)分配記憶體位址;
(2)new乙個instance物件;
(3)將記憶體位址賦值給inst;
cpu為了提高執行效率,這三步操作的順序可以是123,也可以是132。如果是132順序的話,當把記憶體位址賦給inst後,inst指向的記憶體位址上面還沒有new出來單例物件,這時候,如果就拿到inst的話,它其實就是空的,會報空指標異常。這就是為什麼雙重檢查單例模式中,單例物件要加上volatile關鍵字。(
Volatile如何保證可見性
首先要知道記憶體屏障是什麼,記憶體屏障是乙個cpu指令,記憶體屏障是這樣的指令 1,確保特定操作執行的順序 2,影響一些資料的可見性,編譯器和cpu可以保證輸出結果一樣的前提下對指令進行重排序,使得效能優化,當插入乙個記憶體屏障,相當於告訴cpu和編譯器,先於這個命令的必須先執行,後於這個命令的必須...
volatile是如何保證記憶體可見性的
volatile 修飾的變數具備兩種特性 cpu修改資料,首先是對快取的修改,然後再同步回主存,在同步回主存的時候,如果其他cpu也快取了這個資料,就會導致其他cpu快取上的資料失效 通過嗅探匯流排資料傳播,檢查快取對應的主存位址是否被修改過 這樣,當其他cpu再去它的快取讀取這個資料的時候發現快取...
volatile關鍵字如何保證記憶體可見性
一 記憶體可見性 例子1 有乙個全域性的狀態變數open boolean open true 這個變數用來描述對乙個資源的開啟關閉狀態,true表示開啟,false表示關閉,假設有乙個執行緒a,在執行一些操作後將open修改為false 執行緒a resource.close open false ...