zzh

zzh

關於java中volatile可見性適用範圍的一些個人見解

1. volatile 保證了變數值修改的可見性

對於這一點,我們需要了解到在 java 中什麼是變數值。對於基本類型變數,變數值就是賦予它的數值,比如 int a=1,那麼 1 就是基本類型變數 a 的變數值。而對於引用變數類型,變數值就是堆棧中的地址,比如 Object a=new Object (),那麼 0x11111111 就是變數 a 的變數值。
綜上所述,對於基本類型變數,我們為其賦新的值就是修改了其變數值,比如 a=2;而對於引用變數類型,我們修改了其地址就是修改了其變數值,比如 a=new Object ()。

2. 數組類型保證內部元素的可見性

volatile int [] a = new int [4] 其實數組中的各個元素 a [0],a [1],a [2] 以及 a [3] 都具備可見性,而對於其可見性的判斷,可以參考第一條(因為數組中的每一個元素都可以看作是一個變數)。

3. volatile 變量賦值的新變量無法保證可見性

volatile Object a = new Object();
Object b = a;
其中 volatile 無法保證變量 b 的可見性。
在 concurrentHashMap 和 CopyOnWriteArrayList 中我們可以看到不同:
CopyOnWriteArrayList:

image

image

image
可以看到第一張圖中的 a 其實就是 array 本身,因此具備可見性,直接使用 a [index] 可以安全的獲取值。

concurrentHashMap:

image

image
image
其中我們通過第二張圖可以看到 table 被賦值給了一個新的變量 tab,儘管 table 本身被 volatile 修飾,但是新變量 tab 不具備可見性,因此需要使用 Unsafe 中的 getObjectVolatile 來安全地獲取值。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。