程式執行所需要的資料(讀操作)直接來自於記憶體, 而修改變數值(寫操作)實際上有如下三步:
1、將主存中的資料載入到快取中多個執行緒共同操作乙個變數,如下圖2、對快取中的資料進行修改
3、將修改後的值重新整理到記憶體中
第一步:執行緒1、執行緒2、執行緒3操作的是主存中的同乙個變數,並且分別交由cpu1、cpu2、cpu3處理。第二步:3個cpu分別將主存中變數載入到快取中
第三步:各自將修改後的值重新整理到主存總
問題就出現在第二步,因為每個cpu操作的是各自的快取,所以不同的cpu之間是無法感知其他cpu對這個變數的修改的,最終就可能導致結果與我們的預期不符。舉個栗子而使用了volatile關鍵字之後,情況就有所不同,volatile關鍵字有兩層語義:
1、立即將快取中資料寫會到記憶體中
2、其他處理器通過嗅探匯流排上傳播過來了資料監測自己快取的值是不是過期了,如果過期了,就會對應的快取中的資料置為無效。而當處理器對這個資料進行修改時,會重新從記憶體中把資料讀取到快取中進行處理。
在這種情況下,不同的cpu之間就可以感知其他cpu對變數的修改,並重新從記憶體中載入更新後的值,因此可以解決可見性問題。
service類
public
class
service
implements
runnable
public
void
setflag
(boolean flag)
@override
public
void
run(
) system.out.
println
("執行緒結束了");
volatile 記憶體可見性
public class volatilethread implements runnable catch interruptedexception e flag true system.out.println flag isflag public boolean isflag public cla...
Volatile 記憶體可見性
一 當寫乙個volatile變數時,jmm會把該執行緒對應的本地中的共享變數值重新整理到主記憶體。例子 一 volatile 關鍵字 當多個執行緒進行操作共享資料時,可以保證記憶體中的資料可見。相較於 synchronized 是一種較為輕量級的同步策略。注意 1.volatile 不具備 互斥性 ...
Volatile如何保證可見性
首先要知道記憶體屏障是什麼,記憶體屏障是乙個cpu指令,記憶體屏障是這樣的指令 1,確保特定操作執行的順序 2,影響一些資料的可見性,編譯器和cpu可以保證輸出結果一樣的前提下對指令進行重排序,使得效能優化,當插入乙個記憶體屏障,相當於告訴cpu和編譯器,先於這個命令的必須先執行,後於這個命令的必須...