JUC學習筆記之volatile關鍵字——01
一、volatile 關鍵字:當多個執行緒進行操作共享資料時,可以保證記憶體中的資料可見。
相較於 synchronized 是一種較為輕量級的同步策略。
/*TestVolatile.java*/
public class TestVolatile {
public static void main(String[] args) {
ThreadDemo td = new ThreadDemo();
new Thread(td).start();
while(true){
if(td.isFlag()){
System.out.println("------------------");
break;
}
}
//輸出:
//flag=true
}
}
class ThreadDemo implements Runnable {
private volatile
@Override
public void run() {
try {
Thread.sleep(200);
}
catch (InterruptedException e) {
}
flag = true;
System.out.println("flag=" + isFlag());
}
public Boolean isFlag() {
return flag;
}
public void setFlag(Boolean flag) {
this.flag = flag;
}
}
說明:如圖
在程式執行時,JVM會給執行緒分配獨立的記憶體空間,執行緒1更改flag值的時候,是在自己的記憶體中先更改,之後才傳回主存中更改主存的flag值,又因while(true)迴圈的效率太高,main執行緒來不及再去主存中讀資料,因此一直取的是flag=false;這種問題稱為記憶體可見性問題:當多個執行緒操作共享資料時,彼此不可見。
synchronize雖然能解決這個問題,但是效率太低;volatile修飾的都在主存中完成,即不在為每個執行緒單獨拷貝資料,雖然同樣降低了效能,但是比鎖的效率高。
synchronize與volatile的區別:
注意:
1. volatile 不具備“互斥性”
2. volatile 不能保證變數的“原子性”(不可分割性,下篇解釋“原子性”)