volatile關鍵字與可見性

背景

  • 計算機CPU計算過程

計算機在執行程序時,每條指令都是在CPU中執行的,而執行指令過程中,勢必涉及到數據的讀取和寫入。由於程序運行過程中的臨時數據是存放在主存(物理內存)當中的,這時就存在一個問題,由於CPU執行速度很快,而從內存讀取數據和向內存寫入數據的過程跟CPU執行指令的速度比起來要慢的多,因此如果任何時候對數據的操作都要通過和內存的交互來進行,會大大降低指令執行的速度。因此在CPU裡面就有了高速緩存。當程序在運行過程中,會將運算需要的數據從主存複製一份到CPU的高速緩存當中,那麼CPU進行計算時就可以直接從它的高速緩存讀取數據和向其中寫入數據,當運算結束之後,再將高速緩存中的數據刷新到主存當中。

  • 存在問題

單線程中運行是沒有任何問題的,但是在多線程中運行就會有問題了。在多核CPU中,每條線程可能運行於不同的CPU中,因此每個線程運行時有自己的高速緩存。存放在主存(物理內存)中的數據被多個CPU(線程)複製到高速緩存+計算+回寫到主存這些操作後,就會出現主存中的數據與期望計算的結果不一致。

解決方式

通過在總線上加LOCK#鎖的形式可以解決緩存不一致的問題。但是鎖總線開銷比較大, 所以一般是所緩存.

volatile關鍵字的機制

被volatile關鍵字修飾的變量被編譯之後在多核CPU中會引發兩件事情, 用到的就是緩存一致性協議

  • 當前處理器緩存行的額數據回寫到主內存中
  • 這個回寫內存操作會引發其他CPU裡的緩存了該數據的內容失效, 使得其他CPU重新獲取該數據, 從而保證同一個數據在多核CPU中的可見
volatile關鍵字與可見性

緩存一致性協議

  1. 程序以及數據被加載到主內存
  2. 指令和數據被加載到CPU的高速緩存
  3. CPU執行指令,把結果寫到高速緩存
  4. 高速緩存中的數據寫回主內存
volatile關鍵字與可見性

可見性

  • 可見性是指當多個線程訪問同一個變量時,一個線程修改了這個變量的值,其他線程能夠立即看得到修改的值。
最後:
volatile通常被比喻成"輕量級的synchronized",也是Java併發編程中比較重要的一個關鍵字。和synchronized不同,volatile是一個變量修飾符,只能用來修飾變量。無法修飾方法及代碼塊等。volatile關鍵字來保證可見性。當一個共享變量被volatile修飾時,它會保證修改的值會立即被更新到主存,當有其他線程需要讀取時,它會去內存中讀取新值。


分享到:


相關文章: