Java併發程式設計之關鍵字volatile的使用
阿新 • • 發佈:2020-12-29
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;
}
}