下面的**,修改load函式中dosomething(0);傳入的值,從0到4,分別會出現能跳出迴圈和不能跳出迴圈兩種情況
0,什麼也不做,不能跳出迴圈
1,sleep,能跳出迴圈
2,使用system.out.println輸出,能跳出迴圈
3,等待10微秒,不能跳出迴圈
4,等待20微秒,能跳出迴圈
package thread;
public
class
visibilitytest
public
void
load()
system.out.
println
(thread.
currentthread()
.getname()
+"跳出迴圈:i="
+ i);}
public
void
dosomething
(int x)
catch
(interruptedexception e)
break
;case2:
// 能跳出迴圈
system.out.
println
("*****");
// synchronized
break
;case3:
// 不能跳出迴圈
shortwait
(10000);
// 10微秒
break
;case4:
// 能跳出迴圈
shortwait
(20000);
// 20微秒
break
;case0:
// 不能跳出迴圈
default
:// 不能跳出迴圈// do nothingbreak;}}
public
static
void
shortwait
(long interval)
while
(start + interval >= end);}
public
static
void
main
(string[
] args)
catch
(interruptedexception e)
對於threada,會經過read、load操作將flag讀入工作記憶體(本地記憶體),然後use操作寫入cpu core1(暫存器儲存);
對於threadb,也會有上面的步驟。但最後是寫入cpu core2(因為cpu core1一直在被占用),然後給flag賦值為false,再經過assign操作寫回工作記憶體,注意,此時不會立馬執行store、write操作,寫回主記憶體,而是在某一時刻進行;
此時,threada繼續讀取flag,是從工作記憶體中載入的,不是從主記憶體中載入的load函式中dosomething(0);傳入的值,從0到4:
• 0,什麼也不做,while(flag)一直在進行,threada的工作記憶體快取一直有效,因此一直未從主記憶體中讀取,一直是true;
• 1,sleep,會讓出cpu時間片,執行緒上下文切換(儲存現場、恢復現場),因此會從主記憶體中重新讀取flag,讀到了false則跳出迴圈;
注意:與sleep的時間沒有關係,即時sleep0ms,也會讓出cpu時間片;
• 2,使用system.out.println輸出,println方法實現內部有synchronized(this)操作,synchronized會保證可見性,因此會從主記憶體中讀取flag。讀到了false則跳出迴圈;
• 3,等待10微秒,太短了,快取未失效,因此一直未從主記憶體中讀取,一直是true;
• 4,等到20微秒,快取失效了,因此會從主記憶體中讀取,讀到了false則跳出迴圈;
以上問題歸根到底是可見性問題。當執行緒2更改了主記憶體的值後,沒有及時的讓執行緒1知道這個值被更改了。
private volatile boolean flag = true;
上述0-4,執行都會跳出迴圈。
上面例子表示了volatile關鍵字的含義之一:保證變數對所有執行緒的可見性(及時性,一但執行緒1更改了變數,執行緒2立馬知道。底層是通過快取一致性協議。)。
併發程式設計 volatile
併發程式設計中的三個概念 原子性即乙個操作或者多個操作 要麼全部執行並且執行的過程不會被任何因素打斷,要麼就都不執行 可見性指當多個執行緒訪問同乙個變數時,乙個執行緒修改了這個變數的值,其他執行緒能夠立即看得到修改的值 有序性即程式執行的順序按照 的先後順序執行 jvm在真正執行這段 的時候會保證語...
併發程式設計 可見性
這個有人看了嗎?關於volatile 併發安全 可見性的文章 只要我修改一段 加不加volatile,其結果都是一樣的,是為什麼?while getstop 給出兩個觀點 1.由於頻繁訪問stop,所以cpu會把該變數一直放到快取區域,加上volatile會把資料刷回記憶體 然而如果加上sleep ...
Java併發 volatile關鍵字 可見性
1 volatile是輕量級的synchronized,它在多處理器開發中保證了共享變數的 可見性 但無法保證 原子性 2 volatile不會引起執行緒上下文的切換,在使用恰當的情況下,比synchronized的使用和執行成本更低.volatile不需要加鎖,比synchronized更輕量級,...