1

volatile特性
保证可见性,不保证原子性,
读写禁止指令重排序
volatile写操作之前 StoreStore,写之后StoreLoad
volatile读操作之后 LoadLoad LoadStore

image.png

为什么会不一致
1、线程本地内存共享变量的副本读,没有立即同步到主内存,出现了可见性问题。主内存是所有线程共享的,每个线程都有工作内存,不共享线程工作时,把共享变量拷贝到工作内存中,在工作内存中读写写完之后,可能没有立即更新到主存中去,导致其他线程拷贝不到最新数据更新到主存之后,可能也没有立即同步到其他线程中。
2、CPU多级缓存架构,写完L1的数据,不会立即同步到主内存,及时同步到主内存,也可能不会立即加载到其他CPU的L1缓存中,其他的L1缓存使用的还是旧的数据

volatile为什么能保证可见性
数据小于缓存行大小,小于64bytes,MESI缓存一致性协议
数据大于缓存行数据,用总线锁保证数据一致

MESI协议
CPU的缓存行大小为64bytes,每个缓存行使用额外的两位来标记状态
Modified:当数据处于Modified状态时,该CPU会监听缓存行对应主存的数据,一旦监听到,会将缓存行数据写会主存,并标记为Shared
Exclusive:会监听缓存行对应主存的数据读取,一旦监听到,缓存行数据标记为Shared状态。
Shared:会监听缓存行对应主存数据的写入,一旦监听到,缓存行数据变为Invalid状态。
Invalid:读取数据从主存中加载,否则从读取高速缓存。

为什么dcl单例需要volatile

1、NEW designpattern/singleton/TestSingle06
    DUP
2、INVOKESPECIAL designpattern/singleton/TestSingle06.<init> ()V
3、ARETURN

创建对象步骤:
1、对象分配内存地址
2、成员变量赋值
3、引用指向步骤1分配的内存地址

1、2指令不能重排序,23指令可以重排序
如果23重排序了,那么其他线程可能拿到了没有赋成员变量值的对象


一只鱼
49 声望1 粉丝

引用和评论

0 条评论