手写DCL双重验证单例模式
直接上代码
public class Singleton{
private volatile static uniqueInstance;
private Singleton(){ }
public static Singleton getInstance(){
if(uniqueInstance == null){
synchronized (Singleton.class){
if(uniqueInstance == null){
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
单例模式要程序运行期间,有且仅被实例化一次。
第一次判断对象未初始化,进行加锁操作,加锁范围是单例类对象,同一时间只有一个线程可以拿到这个锁资源,保证实例化过程不会并行。
再讲讲为什么要加volatile关键字,对象实例化过程
- 申请内存空间
- 根据对象类型初始化
- 内存地址赋值对象引用
但是JVM执行会有指令重排序,2、3步骤可能乱序执行,单机下不会发生问题,多线程情况,A线程发现未实例化,去申请锁实例化执行到1、3,线程B开始判断,此时uniqueInstance不为空,但是没有初始化,B线程拿到后可能会抛出空指针。
还没有评论,来说两句吧...