public class Singleton {
private static volatile Singleton instance;
private Singleton(){
}
public static Singleton getInstance() {
if (Objects.isNull(instance)) {
synchronized (Singleton.class) {
if (Objects.isNull(instance)) {
instance = new Singleton();
}
}
}
return instance;
}
}
先说说加synchronized关键字原因 , 如果两个线程执行时候 , 都获取到instance , 都为null , 就会同时实例化 , 这就导致结果不是同一个实例了.
然后就是锁里面的判断 , ab线程都读取到这个instance对象为null , a先抢到锁进入实例化 , 实例化完释放锁 , 由于b此时instance对象是null , 所以拿着锁又进行实例化, 这就导致结果又不是同一个实例了.
接着就是最外层的判断 , 主要是在instance被实例化外, 为了不让其他线程继续等待拿到锁再判断 , 直接在最外层判断可以优化线程, 节省时间
最后就是volatile 关键字, 是为了防止指令重排序 , 做到一旦实例化就马上将数据加载到内存 , 避免更多线程进入第一层判断, 主要也是优化的作用. 至于防止指令重排序可以自己去百度查下.
面试的时候 , 如果面试官让你手写单例 , 基本上就是为了考察你懒汉式 , 把这个写上完美通关 !