双重检验的单例模式是比较推荐的单例写法,在该代码中的单例对象的是用volatile关键字修饰的。这时就产生的一个疑问,为什么需要volatile来修饰呢?
上网查看多个博客,下面简单通俗分析一下当中的原因:
贴上不加volatile单例代码

public class Singleton {
    private static Singleton s;
    private Singleton(){};
    public static Singleton getInstance() {  //1
        if(s == null) { //2
            synchronized (Singleton.class) { //3
                if(s == null) { //4
                    s = new Singleton(); //5
                }
            }
        }
        return s; //6
    }
}

1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

以前不了解为什么需要volatile关键字,后来发现在并发情况下,如果没有volatile关键字,在第5行会出现问题
对于第5行 s = new Singleton(); //5
可以分解为3个步骤:

1 memory=allocate();// 分配内存 相当于c的malloc
2 ctorInstanc(memory) //初始化对象
3 s=memory //设置s指向刚分配的地址

上面的代码在编译器运行时,可能会出现重排序 从1-2-3 排序为1-3-2

如此在多线程下就会出现问题

例如现在有2个线程A,B

线程A在执行第5行代码时,B线程进来,而此时A执行了 1和3,没有执行2,此时B线程判断s不为null 直接返回一个未初始化的对象,就会出现问题

而用了volatile,上面的重排序就会在多线程环境中禁止,不会出现上述问题。
正确双重检验单例模式写法:

public class Singleton {
    private static volatile Singleton s;
    private Singleton(){};
    public static Singleton getInstance() {
        if(s == null) {
            synchronized (Singleton.class) {
                if(s == null) {
                    s = new Singleton();
                }
            }
        }
        return s;
    }
}

1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

总结:加上volatile就是为了防止产生指令的重排序问题
为什么volatile能禁止指令的重排序呢?这里就涉及到volatile的原理了,这里就不多说volatile的原理,可以看看海子大神的博客:volatile关键字解析
---------------------
作者:Tuzki_小辣鸡
来源:CSDN
原文:https://blog.csdn.net/weixin_37659242/article/details/82776198
版权声明:本文为博主原创文章,转载请附上博文链接!

最新文章

  1. 以下C#程序的输出结果是( )。
  2. Rectangles Area Sum
  3. C#中动态读写App.config配置文件
  4. 移动开发js库Zepto.js应用详解
  5. XML xsd
  6. input上传图片预览
  7. js克隆
  8. Linux的软连接与硬链接
  9. 【转】MATLAB在一幅图上添加多个纵坐标轴
  10. 【Android学习】调用系统相机
  11. 机器学习笔记-1 Linear Regression with Multiple Variables(week 2)
  12. Reactjs vs. Vuejs
  13. 实现线程安全先进先出的dict
  14. 记一次mariadb升级故障
  15. C#集合类型大揭秘 【转载】
  16. GMA Round 1 大吉大利,晚上吃鸡
  17. python第九十天----jquery
  18. 2018/03/08 每日一个Linux命令 之 chattr/lsattr
  19. 别人不会给你说的---C语言中数组名和指针的区别 及 sizeof用法
  20. SSH三大框架需要的配置文件

热门文章

  1. std::string begin end
  2. 【AI】Computing Machinery and Intelligence - 计算机器与智能
  3. 【LeetCode】Longest Substring with At Most Two Distinct Characters (2 solutions)
  4. Spring 3.0 AOP 之 AOP 术语 (一)
  5. C语言open()函数:打开文件函数(转)
  6. Docker(一):Docker入门教程
  7. 忘记mysqlroot密码/我的电脑 管理服务里面没有mysql启动项/mysql启动不了net start mysql
  8. 必须掌握的30种SQL语句优化
  9. 【Oracle】Oracle基本数据类型总结
  10. windows 7 开启无线wifi