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 来安全地获取值。

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。