Java多執行緒/併發09、淺談volatile
首先宣告:現在JVM經過優化,已不會出現liveness failure 。所以沒事別用volatile。
在瞭解volatile之前,先介紹一個名詞:liveness failure ,直譯叫作活性失敗。因為這是volatile很重要的一個應用場景:
public class volatileDemo {
private static boolean stopFlag;
public static void main(String[] args) throws InterruptedException {
Thread volatileThread =new Thread(){
@Override
public void run() {
while(!stopFlag){
System.out.print(Calendar.getInstance().get(Calendar.SECOND)+",");
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
volatileThread.start();
Thread.sleep(3000);
stopFlag=true;
}
}
執行幾秒鐘之後,發現並沒有終止輸出。(jre1.7之前會出現)
主執行緒修改了變數stopFlag,子執行緒B卻沒有感知,稱為活性失敗。
Java記憶體模型(JMM)規定了所有的變數都儲存在主記憶體中,主記憶體中的變數為共享變數,而每條執行緒都有自己的工作記憶體,執行緒的工作記憶體儲存了從主記憶體拷貝的變數,所有對變數的操作都在自己的工作記憶體中進行,完成後再重新整理到主記憶體中。
程式碼stopFlag=true;主執行緒(執行緒main)雖然對stopFlag的變數進行了修改且重新整理回主記憶體中(《深入理解java虛擬機器》中關於主記憶體與工作記憶體的互動協議提到變數在工作記憶體中改變後必須將該變化同步回主記憶體),但volatileThread執行緒讀的仍是自己工作記憶體的舊值導致出現多執行緒的可見性問題,解決辦法就是給stopFlag變數加上volatile關鍵字。
據effective Java中描述,這個問題涉及到JVM對while(!flag)這種形式有一個提升的優化,即:
while(!flag){}
進行提升優化:
if(flag){
while(true){}
}
重點參考文章:
http://www.ibm.com/developerworks/cn/java/j-jtp06197.html
http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html
總結如下
- volatile重要工作是避免執行緒髒讀:當執行緒對volatile變數進行讀操作時,會先將自己工作記憶體中的變數置為無效,之後再通過主記憶體拷貝新值到工作記憶體中使用。
- volatile解決的是變數在多個執行緒之間的可見性,但不能完全保證資料的原子性。
- 現在JVM經過優化,已不會出現liveness failure 。所以沒事別用volatile。
相關文章
- 【多執行緒與高併發】- 淺談volatile執行緒
- 淺談 Java多執行緒Java執行緒
- 【多執行緒與高併發 2】volatile 篇執行緒
- Java多執行緒(四):volatileJava執行緒
- Java多執行緒(六) volatileJava執行緒
- JAVA多執行緒併發Java執行緒
- 淺談多執行緒執行緒
- java多執行緒之volatile理解Java執行緒
- java多執行緒與併發 - 執行緒池詳解Java執行緒
- java多執行緒與併發 - 併發工具類Java執行緒
- 深入理解Java多執行緒與併發框(第⑦篇)——volatile 關鍵字Java執行緒
- Java多執行緒(二)volatile關鍵字Java執行緒
- java多執行緒4:volatile關鍵字Java執行緒
- JAVA多執行緒和併發基礎Java執行緒
- Java多執行緒與併發之ThreadLocalJava執行緒thread
- Java併發/多執行緒-CAS原理分析Java執行緒
- Java多執行緒開發|volatile與偽共享問題Java執行緒
- Java併發指南1:併發基礎與Java多執行緒Java執行緒
- 深入淺出Java多執行緒Java執行緒
- 深入淺出Java多執行緒(十二):執行緒池Java執行緒
- Java多執行緒和併發問題集Java執行緒
- Java高併發與多執行緒(一)-----概念Java執行緒
- 多執行緒併發篇——如何停止執行緒執行緒
- java多執行緒的雜談Java執行緒
- Java高併發與多執行緒(二)-----執行緒的實現方式Java執行緒
- 多執行緒與高併發(一)多執行緒入門執行緒
- 多執行緒與高併發(二)執行緒安全執行緒
- 併發與多執行緒之執行緒安全篇執行緒
- Java多執行緒學習(三)volatile關鍵字Java執行緒
- 併發程式設計之volatile與JMM多執行緒記憶體模型程式設計執行緒記憶體模型
- Java併發(四)----執行緒執行原理Java執行緒
- 淺談JS執行緒JS執行緒
- 執行緒概念淺談執行緒
- 多執行緒系列(十一) -淺析併發讀寫鎖StampedLock執行緒
- Java併發 之 執行緒池系列 (1) 讓多執行緒不再坑爹的執行緒池Java執行緒
- Java併發(一)----程式、執行緒、並行、併發Java執行緒並行
- 淺談Java併發Java
- Java 執行緒和 volatile 解釋Java執行緒
- java基礎(五):談談java中的多執行緒Java執行緒