function0413 2017-03-17 08:32 采纳率: 66.7%
浏览 2300
已采纳

单例模式中,懒汉式到底该不该使用双重检查锁?

很多人说因为内存什么的原因,双重检查锁可能会失效,小白实在看不太懂,
只想知道结论是什么?双重检查锁到底该不该用?
如果不该用,那单例模式更好的写法是什么?

附代码

 class SingleTon2 {
    private static SingleTon2 s2 = null;

    public static SingleTon2 getInstance() {
        if (s2 == null) {

            synchronized (SingleTon2.class) {

                if (s2 == null) {
                    s2 = new SingleTon2();
                }
            }
        }
        return s2;
    }

    private SingleTon2() {
        System.out.println("懒汉式初始化.......");
    }

}
  • 写回答

1条回答 默认 最新

  • zhangxl 2017-03-17 09:00
    关注

    双重检查锁在多线程并发时,可能会因为JVM指令重排出问题
    代码中 s2 = new SingleTon2();在JVM中可能会分解为:
    memory = allocate(); //1:分配对象的内存空间
    initInstance(memory); //2:初始化对象
    instance = memory; //3:设置instance指向刚分配的内存地址

    如果因为某些原因导致指令重排,指令的执行顺序可能为:
    memory = allocate(); //1:分配对象的内存空间
    instance = memory; //3:设置instance指向刚分配的内存地址,此时对象还没被初始化
    initInstance(memory); //2:初始化对象

    此时,如果在instance=memory执行,但未完成对象初始化时,另一个线程执行第一个if(s2==null)会返回false直接返回未初始化的
    Singleton实例,导致错误。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥100 求数学坐标画圆以及直线的算法
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考
  • ¥15 名为“Product”的列已属于此 DataTable
  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 自己瞎改改,结果现在又运行不了了
  • ¥15 链式存储应该如何解决
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站