java volatile關鍵字的含義詳細引見。本站提示廣大學習愛好者:(java volatile關鍵字的含義詳細引見)文章只能為提供參考,不一定能成為您想要的結果。以下是java volatile關鍵字的含義詳細引見正文
java volatile關鍵字
在java線程並發處置中,有一個關鍵字volatile的運用目前存在很大的混雜,以為運用這個關鍵字,在停止多線程並發處置的時分就可以萬事大吉。
Java言語是支持多線程的,為理解決線程並發的問題,在言語外部引入了 同步塊 和 volatile 關鍵字機制。
synchronized
同步塊大家都比擬熟習,經過 synchronized 關鍵字來完成,一切加上synchronized 和 塊語句,在多線程訪問的時分,同一時辰只能有一個線程可以用
synchronized 修飾的辦法 或許 代碼塊。
volatile
用volatile修飾的變量,線程在每次運用變量的時分,都會讀取變量修正後的最的值。volatile很容易被誤用,用來停止原子性操作。
上面看一個例子,我們完成一個計數器,每次線程啟動的時分,會調用計數器inc辦法,對計數器停止加一
執行環境——jdk版本:jdk1.6.0_31 ,內存 :3G cpu:x86 2.4G
public class Counter { public static int count = 0; public static void inc() { //這裡延遲1毫秒,使得後果分明 try { Thread.sleep(1); } catch (InterruptedException e) { } count++; } public static void main(String[] args) { //同時啟動1000個線程,去停止i++計算,看看實踐後果 for (int i = 0; i < 1000; i++) { new Thread(new Runnable() { @Override public void run() { Counter.inc(); } }).start(); } //這裡每次運轉的值都有能夠不同,能夠為1000 System.out.println("運轉後果:Counter.count=" + Counter.count); } }
運轉後果:Counter.count=
995
實踐運算後果每次能夠都不一樣,本機的後果為:運轉後果:Counter.count=
995
,可以看出,在多線程的環境下,Counter.count並沒有希冀後果是
1000
很多人以為,這個是多線程並提問題,只需求在變量count之前加上
volatile
就可以防止這個問題,那我們在修正代碼看看,看看後果是不是契合我們的希冀
public class Counter { public volatile static int count = 0; public static void inc() { //這裡延遲1毫秒,使得後果分明 try { Thread.sleep(1); } catch (InterruptedException e) { } count++; } public static void main(String[] args) { //同時啟動1000個線程,去停止i++計算,看看實踐後果 for (int i = 0; i < 1000; i++) { new Thread(new Runnable() { @Override public void run() { Counter.inc(); } }).start(); } //這裡每次運轉的值都有能夠不同,能夠為1000 System.out.println("運轉後果:Counter.count=" + Counter.count); } }
運轉後果:Counter.count=992
運轉後果還是沒有我們希冀的1000,上面我們剖析一下緣由
在 java 渣滓回收整理一文中,描繪了jvm運轉時辰內存的分配。其中有一個內存區域是jvm虛擬機棧,每一個線程運轉時都有一個線程棧,
線程棧保管了線程運轉時分變量值信息。當線程訪問某一個對象時分值的時分,首先經過對象的援用找到對應在堆內存的變量的值,然後把堆內存
變量的詳細值load到線程本地內存中,樹立一個變量正本,之後線程就不再和對象在堆內存變量值有任何關系,而是直接修正正本變量的值,
在修正完之後的某一個時辰(線程加入之前),自動把線程變量正本的值回寫到對象在堆中變量。這樣在堆中的對象的值就發生變化了。上面一幅圖
描繪這寫交互
read and load 從主存復制變量到以後任務內存
use and assign 執行代碼,改動共享變量值
store and write 用任務內存數據刷新主存相關內容
其中use and assign 可以屢次呈現
但是這一些操作並不是原子性,也就是 在read load之後,假如主內存count變量發作修正之後,線程任務內存中的值由於曾經加載,不會發生對應的變化,所以計算出來的後果會和預期不一樣
關於volatile修飾的變量,jvm虛擬機只是保證從主內存加載到線程任務內存的值是最新的
例如假設線程1,線程2 在停止read,load 操作中,發現主內存中count的值都是5,那麼都會加載這個最新的值
在線程1堆count停止修正之後,會write到主內存中,主內存中的count變量就會變為6
線程2由於曾經停止read,load操作,在停止運算之後,也會更新主內存count的變量值為6
招致兩個線程及時用volatile關鍵字修正之後,還是會存在並發的狀況。
感激閱讀,希望能協助到大家,謝謝大家對本站的支持!