一、volatile的解釋
當乙個共享變數被volatile修飾時,它會保證修改的值會立即被更新到主存,當有其他執行緒需要讀取時,它會去記憶體中讀取新值。
二、問題的發現
從volatile的定義上來看它看似應該能保證多個執行緒對volatile變數使用的同步,那麼先來看一段**。
package com;
public class main
});threads[i].start();
} // 主線程等待每個執行緒執行完成
for (int i = 0; i < 1000; i++) catch (interruptedexception e)
} //結果如果出現不是1000,則出現了同步問題
system.out.println("執行結果:counter.count=" + main.count);
}}
這段**的執行結果為:
執行結果:counter.count=998
三、分析和結論
從上面**的執行結果上來看,顯然voltile沒有達到我們想要的效果(讓couter=1000),那麼這是什麼原因呢?其實volatile只能保證快取一致性,或者說併發程式設計中的可見性——即乙個執行緒對volatile變數的修改會立即更新到主存,其他執行緒在使用該變數的時候會從主存讀取最新的值。
但是——————它不能保證原子性!!!
我們假設有a、b、c三個執行緒和volatile變數x=0
a——x=1
b——x=x+1
c——x=x+2;
設想如下執**況,(1)a執行完,此時x=1 (2)b、c開始同時執行,從主存中讀取最新的值到工作記憶體
(3)b、c同時執行加運算(4)b寫入主存,c寫入主存
以上執**況並沒有違反volatile的規定,因為b、c同時讀到了最新的值,但是在b寫入主存的時候,c已經執行完加運算,不要讀取最新的x值了,因此連續兩次覆蓋寫入,導致了執行緒同步不理想。
那麼這裡的原子性沒有得到保證是指什麼呢?——讀和寫的操作不是原子性的!
JAVA中的volatile關鍵字
大家最熟悉的保證執行緒安全的技術是lock和synchronized塊 後面就統稱鎖了 但如果在一些對排他性 一會介紹 沒有太多限制的變數上使用鎖會花費很多時間和資源,為了優化程式效能,就有了volatile。鎖提供兩種特性 排他性和可見性。排他性很好理解,就是只有乙個執行緒可以對鎖住的東東進行操作...
Java中的volatile關鍵字
執行緒1 boolean stop false while stop 執行緒2 stop true 第二 使用volatile關鍵字的話,當執行緒2進行修改時,會導致執行緒1的工作記憶體中快取變數stop的快取行無效 反映到硬體層的話,就是cpu的l1或者l2快取中對應的快取行無效 第三 由於執行緒...
java多執行緒中volatile的理解
一 使用runnable來實現多執行緒 package com.xiancheng.old public class threadold implements runnable catch interruptedexception e falg true public boolean isfalg ...