手写单例双重检查
直接上代码,稍后简单分析一下:
public class Singleton{
// 创建私有的构造方法
private Singleton(){}
// 私有化成员变量
private static volatile Singleton instance = null;
//公共的获取成员变量的方法
public static Singleton getInstance(){
if(instance == null){
synchronized(Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
总结:
1:单例模式总结
(1)私有化构造方法,防止外部调用构造方法初始化
(2)私有化成员变量,防止外部直接使用
(3)提供公共方法,用于获取内部私有化的单例对象(经评论区提醒,忘了添加 static关键字
)
2:为什么要用 volatile
关键字修饰
(1)这个其实就需要讨论到 volatile
关键字的几个特性了,(经评论区提醒,不具有原子性
,请注意这个问题),有序性
,可见性
其中主要是涉及到 可见性
图片中 getInstance 方法应该添加 static 关键字
两个线程A和B
如图,此时A线程获取到锁,B未获取到锁,处于阻塞状态
当A线程创建对象,释放锁之后
B获取到锁,判断 instance 是否等于 null,
由于 volatile 关键字的原因,会将A线程修改的 instance的对象刷新到主内存中,会保证 B线程可以看到 此时A线程已经修改了instance的状态,此时B线程判断 instance 不为 null,直接返回,保证了多线程情况下,单例模式的正确性
如果没有关键字volatile
的话,在多线程情况下,没办法保证单例的正确性
至此,我觉得通过以上的说明,为什么需要双重检查,应该也可以理解了