【学习日志】volatile关键字的作用
- 消除指令重排序
- 保证了不同线程对变量进行操作时的可见性,cpu对变量值修改后,其他线程读取变量信息时从内存读取而非cpu缓存
使用场景:
1. 双重检查锁,防止重排序
uniqueSingleton = new Singleton();
赋值操作在编译后不是原子的,分为三步:
(1)分配内存空间
(2)初始化对象
(3)将引用对象指针指向分配的内存空间地址
如果重排序,可能出现:
(1)分配内存空间
(2)将引用对象指针指向分配的内存空间地址
(3)初始化对象
即如下代码,如果没有加volatile,指令重排序后则可能出现Thread1执行到赋值的第二步((2)将引用对象指针指向分配的内存空间地址),Thread2执行获取,拿到的是未完成初始化的对象
public class Singleton { private volatile static Singleton uniqueSingleton; private Singleton() { } public Singleton getInstance() { if (null == uniqueSingleton) { synchronized (Singleton.class) { if (null == uniqueSingleton) { uniqueSingleton = new Singleton(); } } } return uniqueSingleton; } }