volatile關鍵字
什么是可見性?
可見性是指執行緒A改變變數的值后,執行緒B可以馬上看到更改后變數的值
volatile的作用
關鍵字volatile提示執行緒每次從共享記憶體中讀取資料,而不是從私有記憶體中讀取,這樣就保證了同步資料的可見性
關鍵字volatile適用的場景
當想實作一個執行緒對一個變數進行修改,希望其他執行緒可以取到最新的值的時候,就需要對變數使用volatile關鍵字了
我們舉一個例子:
import static java.lang.Thread.sleep;
public class VolatileTest {
public static boolean flag = true;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("執行緒1 開始!");
while(flag){
}
System.out.println("執行緒1 結束!");
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("執行緒2 開始!");
flag = false;
System.out.println("flag = " + flag);
}
});
t1.start();
sleep(2000);
t2.start();
}
}
- 運行結果

我們可以看到:程式在一直運行,進入了死回圈,那么是什么原因造成出現了死回圈呢?
- 我么在啟動執行緒t1之后,變數“public static boolean flag = true;”存在于公共堆疊及執行緒私有的堆疊中,
t1運行后一直在執行緒私有堆疊中取得的flag的值是true,而執行緒2的代碼“flag = false;”,修改的是公共堆疊中的
flag,所以t1執行緒私有堆疊中的flag仍然是true,
解決方法 -添加volatile關鍵字
修改“public static volatile boolean flag = true;”,我們再次運行程式

volatile是否具有原子性?
關鍵字volatile最大的缺點是不支持原子性,如果修改實體中的資料,比如i++,這樣的操作不是原子操作,分為三步
- 從記憶體中取i的值
- 計算i的值
- 將i的值存入記憶體中
如果在第二步計算i的值時,其他執行緒讀取i的值,并對i進行修改,這個時候就會出現臟資料,解決方法是使用synchronized關鍵字
- 參考資料《Java多執行緒編程核心技術 第二版》
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/469696.html
標籤:其他
