双重校验锁实现对象单例
双重校验锁实现对象单例
- 在Java中,
volatile关键字除了可以保证变量的可见性,还有一个重要的作用就是防止JVM的指令重排序 - 如果将变量声明为
volatile,那么在对这个变量进行读写操作时,会通过插入特定的内存屏障的方式来禁止指令重排 unsafe类中的内存屏障相关方法:public native void loadFence();:加载屏障,确保在它之前的读操作不会被重排序到它之后public native void storeFence();:存储屏障,确保在它之前的写操作不会被重排序到它之后public native void fullFence();:完全屏障,确保在它之前的读写操作都不会被重排序到它之后
1. 双重校验锁实现单例模式(线程安全)
1 | public class Singleton { |
uniqueInstance采用volatile关键字修饰也是很有必要的uniqueInstance = new Singleton();这行代码实际上可以分解为以下三个步骤:- 为
uniqueInstance分配内存空间 - 初始化
uniqueInstance - 将
uniqueInstance指向分配的内存地址
- 为
- 由于JVM的指令重排序优化,执行顺序可能变成1->3->2,这样单线程下不会有问题,但是多线程下就会出现某个线程获得没有初始化的实例。
