6.22Java多執行緒volitale
阿新 • • 發佈:2021-06-23
volitale說明
作用:
保證執行緒間變數的可見性(注意:不是執行緒之間的變數可見)
執行緒A對變數X進行修改後,線上程A後面執行的其他執行緒能看到變數X的變動。
需要符合以下兩個規則:
-
執行緒對變數進行修改之後要立刻寫回到主記憶體--->防止主記憶體與工作記憶體中不一致的情況
-
加了volitale修飾,對變數的修改就會立刻寫到主記憶體當中
-
同時通知另一個執行緒拿到最新的
-
-
執行緒對變數讀取的時候要從主記憶體中讀,而不是從快取中讀
執行緒工作模式圖:
特點:
-
各執行緒的工作記憶體間彼此獨立、互不可見。
-
線上程啟動的時候,虛擬機器為每個記憶體分配一塊工作記憶體。
-
包含了執行緒內部定義的區域性變數
-
執行緒所需要使用的共享變數(非執行緒內構造的物件)的副本
-
volatile的缺陷:--->只保證了同步的資料可見
volatile不能保證原子性
什麼是原子性?
以程式碼a++舉例,在彙編層面會分成三步
-
拿到a
-
a+1計算結果
-
儲存計算的結果到a中
這完整的三步是一個整體、一個變數。--->volatile不能保證這三個作為一個整體發生變化
volatile例項demo
package thread.rearrangement;
/**
* volatile用於保證資料的同步
* 可見性
* 粒度很小,只保證資料的同步
* 不保證原子性,可以避免指令重排!!!
* @since JDk 1.8
* @date 2021/6/22
* @author Lucifer
*/
public class VolatileTestNo1 {
/*加一個類變數*/
private volatile static int num = 0;
public static void main(String[] args) {
/*使用lambda表示式多執行緒操作變數*/
new Thread(() -> {
/*寫一個死迴圈*/
while (num==0){
//這裡不要編寫程式碼--->目的是讓cpu繁忙
}
}).start();
/*一秒後改變值為1*/
try {
Thread.sleep(1000);
}catch (InterruptedException e){
System.out.println(e.getMessage());
e.printStackTrace();
}
/*改變變數的值*/
num = 1;
}
/*
如果不加volatile那麼執行緒不會停止
加了volatile以後一秒後num已經發生改變,雖然不會回顯(因為事務沒有回寫到主存)但是執行緒一樣會停止
保證資料的可見性,保證資料的重排
不保證賦值操作的原子性
*/
}