1. 程式人生 > 其它 >Java併發程式設計之關鍵字volatile的使用

Java併發程式設計之關鍵字volatile的使用

volatile關鍵字的作用

1.可以保證不同執行緒間volatile變數的一致性。但是不能保證原子操作。
2.可以禁止指令重排。

一致性

cpu會將經常使用的值加入到快取中從而加快讀取速度。每次修改變數的值時,首先會在快取中完成修改,此時記憶體中的值還沒有改變。(至於什麼時候寫回記憶體則不確定(會在合適的時候)這樣就會出現併發問題)。用volatile修飾的變數會在值改變後,立即修改記憶體中的值。從而保證不同執行緒間volatile值的一致性。

例子

用volatile修飾

public class Test1 {
    //用volatile修飾
    volatile int temp =
0; int i = 0; public static void main(String[] args) throws InterruptedException { Test1 t1 = new Test1(); Thread thread1 = new Thread(()->{ t1.fun1();}); Thread thread2 = new Thread(()->{ t1.fun1();}); Thread thread3 = new Thread(
()->{ t1.fun1();}); Thread thread4 = new Thread(()->{ t1.fun1();}); thread1.start(); thread2.start(); thread3.start(); thread4.start(); Thread.sleep(1000); t1.temp = 1; } void fun1(){ while (temp==0){ }
} }

上述程式可以結束
在這裡插入圖片描述

volatile int temp = 0;改成int temp = 0;後此程式將一直迴圈下去。

禁止指令重排

JVM可以通過改變指令的執行順序從而加快執行效率。(保證在本執行緒中的執行結果不變)

例子

public class Test3 {
    //雙端檢索模式中用volatile防止指令重排
    volatile static Test3 t3;
    static Test3 getTest3(){
        if(t3==null){
            synchronized (Test3.class){
                if(t3==null){
                    t3 = new Test3();
                }
            }
        }
        return t3;
    }
}