美文网首页
单例模式双重校验的再理解

单例模式双重校验的再理解

作者: 路得自己走 | 来源:发表于2019-08-19 19:11 被阅读0次

    提起单例模式,作为攻城狮的你我都不会感觉到陌生,而为了确保在程序中的线程安全,我们常常会倾向于双重校验和静态类两种方式。而且众所周知,在双重校验的方式中,我们发现了关键字volatile的身影,而且一直以来小编只是知道 该关键字可以保证操作之间的可见性。但是只知其一啊,今天突然明白这其中的道理:

    public class Singleton {
    private volatile static Singleton singleton;
    private Singleton (){}
    public static Singleton getSingleton() {
    if (singleton == null) {
    synchronized (Singleton.class) {
    if (singleton == null) {
    singleton = new Singleton();
    }
    }
    }
    return singleton;
    }
    }
    如上述代码片所示,singleton变量使用了volatile关键字修饰,也就意味着这个变量对接下来的操作具有可见性(原因稍后会有解释)。
    ♗ 如果上述代码中singleton变量去掉volatile关键字……

    public class Singleton {
    private static Singleton singleton;
    private Singleton (){}
    public static Singleton getSingleton() {
    if (singleton == null) {
    synchronized (Singleton.class) {
    if (singleton == null) {
    singleton = new Singleton();
    }
    }
    }
    return singleton;
    }
    }
    如上述代码所示,如果是单线程操作,由于代码的顺序间接的决定了执行顺序,而且在单线程中,即使jvm执行了顺序重排,仍然不会出现问题;

    在讨论多线程的场景之前,我们先来科普一下 对象初始化的过程:在对象初始化也就是如第八行代码(singleton = new Singleton();  )所示,要知道,这行代码一共有三个过程:
    
    分配对象的内存空间-->初始化对象 --> 将singleton指向刚分配好的内存地址
    

    -----------------------------------------我是分割线-------------------------------------------

    明白初始化的过程之后,我们开始讨论多线程的场景:假设现在有线程A和线程B,当两个线程同时来访问Singleton对象,但是在访问期间会有以下不安全的情况:
    

    1)A /B 线程同时访问,这时两个线程都发现singleton为空,所以两个线程都会创建一个singleton变量,这自然不符合单例模式的初衷……

    2)在不同的时间,A、B线程分别来访问这个Singleton对象,可能会出现报错的情况:

            ![image.png](https://img.haomeiwen.com/i4587933/bb1b30c485451510.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    
     如上图所示,线程B在T4时间的访问一定会出现NullPointerException,因为找不到这个对象噻!
    
     关于volatile修饰之后,为什么就可以避免上图中多线程访问的问题,将在下篇中讲解,敬请期待!
    

    ————————————————
    版权声明:本文为CSDN博主「杨士超」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/YSC1123/article/details/77867138

    相关文章

      网友评论

          本文标题:单例模式双重校验的再理解

          本文链接:https://www.haomeiwen.com/subject/iieesctx.html