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執行緒
- java多執行緒與併發 - volatile的作用及原理Java執行緒
- Java多執行緒——volatileJava執行緒
- JAVA多執行緒併發Java執行緒
- 【多執行緒與高併發 2】volatile 篇執行緒
- 淺談多執行緒執行緒
- Java多執行緒(四):volatileJava執行緒
- Java多執行緒(六) volatileJava執行緒
- java 多執行緒 併發 面試Java執行緒面試
- ]淺談幾種伺服器端模型——多執行緒併發式(執行緒池)伺服器模型執行緒
- Java 併發和多執行緒(一) Java併發性和多執行緒介紹[轉]Java執行緒
- java多執行緒之volatile理解Java執行緒
- Java多執行緒之初識volatileJava執行緒
- Java併發和多執行緒:序Java執行緒
- java多執行緒與併發 - 併發工具類Java執行緒
- java多執行緒與併發 - 執行緒池詳解Java執行緒
- Java多執行緒/併發08、中斷執行緒 interrupt()Java執行緒
- Java多執行緒/併發12、多執行緒訪問static變數Java執行緒變數
- JAVA多執行緒和併發基礎Java執行緒
- Java併發/多執行緒-CAS原理分析Java執行緒
- Java併發指南1:併發基礎與Java多執行緒Java執行緒
- 深入理解Java多執行緒與併發框(第⑦篇)——volatile 關鍵字Java執行緒
- 【java 多執行緒】多執行緒併發同步問題及解決方法Java執行緒
- Java多執行緒/併發06、執行緒鎖Lock與ReadWriteLockJava執行緒
- Java併發和多執行緒1:併發框架基本示例Java執行緒框架
- java多執行緒詳解(併發,並行,同步)Java執行緒並行
- Java多執行緒開發|volatile與偽共享問題Java執行緒
- Java多執行緒(二)volatile關鍵字Java執行緒
- java多執行緒4:volatile關鍵字Java執行緒
- 多執行緒併發篇——如何停止執行緒執行緒
- Java多執行緒與併發之ThreadLocalJava執行緒thread
- Java高併發與多執行緒(一)-----概念Java執行緒
- Java多執行緒和併發問題集Java執行緒
- Java多執行緒與併發 - 瞭解“monitor”Java執行緒
- Java學習之併發多執行緒理解Java執行緒
- 深入淺出Java多執行緒Java執行緒
- 深入淺出Java多執行緒(十二):執行緒池Java執行緒