理解Java中的Volatile關鍵字(demo)

什麼是volatile

關鍵字volatile 提供了Java 虛擬機中最輕量級的同步機制。在meidium 中有篇文章說:Volatile specifier is used to indicate that a variable’s value can be modified by multiple threads simultaneously

當你使用了volatile之後,那麼這個變量會有如下的特性:

  • 保證此變量對所有的線程的可見性
  • 禁止指令重排序優化

對於第一條的內容,volatile是如何保證讀寫操作對所有的線程可見?

這裏涉及到可見性的問題。

對於普通的變量來說,每個線程要想修改變量的值,首先從主存(Main Mermory, 也就是我們通常所說的)中拷貝值到自己所屬的CPU cache中去。現在的處理器,一般是會有多個CPU的,
每個線程可能運行在不同的CPU, 那麼線程修改完成的值,是首先保存在CPU cache中去。此時其他的線程是察覺不到修改的結果的,這就造成了併發
模型中的可見性問題。

考慮這樣一種情況:

public class SharedObject { 
   public int counter = 0;
}

現在有兩個線程, 線程1和線程2, 他們不時會去讀取這個共享變量。如果counter 沒有聲明volatile這個關鍵字,那麼此時就無法保證counter的值何時從CPU緩存寫回到主存。這意味着,counter在CPU cache中的值和主存中的會不一致。

但是如果聲明瞭volatile的話,對volatile變量進行寫操作的話,那麼JVM就會向處理器發送一條LOCK前綴的指令,將這個變量所在緩存行中的數據寫回到系統內存。

寫回的過程,爲了保證各個處理器的緩存是一一致的,就會實現緩存一致性協議。

緩存不停地窺探總線上發生的數據交換,來檢查自己的數據是不是已經過期了。如果發現此時緩存行中的值已經失效的話,就會將當前緩存行中的值設置爲無效狀態。處理器要用到這個值的話,就會從內存中重新獲取這個值。

禁止指令重排序

指令重排序是指CPU採用了允許將多條指令不按照程序規定的順序分開發送給各相應的電路單元處理

參考:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章