volatile如何保證可見性和防止重排序

2021-10-01 07:08:08 字數 881 閱讀 9923

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 ...