为了账号安全,请及时绑定邮箱和手机立即绑定

Java双重检查锁定

/ 猿问

Java双重检查锁定

叮当猫咪 2019-10-18 15:07:22

我偶然遇到了一篇文章,该文章最近讨论了Java中的双重检查锁定模式及其陷阱,现在我想知道我多年来使用的这种模式的变体是否会遇到任何问题。


我看过很多关于该主题的文章和文章,并了解了对部分构造的对象的引用所带来的潜在问题,据我所知,我认为我的实现不受这些问题的影响。以下模式是否有问题?


而且,如果没有,人们为什么不使用它?在围绕此问题进行的任何讨论中,我从未见过推荐它的方法。


public class Test {

    private static Test instance;

    private static boolean initialized = false;


    public static Test getInstance() {

        if (!initialized) {

            synchronized (Test.class) {

                if (!initialized) {

                    instance = new Test();

                    initialized = true;

                }

            }

        }

        return instance;

    }

}


查看完整描述

3 回答

?
MYYA

双重检查锁定已损坏。由于初始化是原语,因此它可能不需要易失性即可工作,但是在实例初始化之前,没有什么可以阻止初始化被视为对非同步代码是正确的。


编辑:为了澄清上述答案,原始问题询问有关使用布尔值来控制双重检查锁定的问题。如果没有以上链接中的解决方案,它将无法正常工作。您可以仔细检查锁,实际上是设置一个布尔值,但是在创建类实例时,仍然存在有关指令重新排序的问题。建议的解决方案不起作用,因为在非同步块中看到已初始化的布尔值为true后,实例可能未初始化。


仔细检查锁定的正确解决方案是使用volatile(在实例字段上)并忽略初始化的布尔值,并确保使用JDK 1.5或更高版本,或在最终字段中对其进行初始化(如链接中所述)文章和汤姆的答案,或者只是不使用它。


当然,整个概念似乎是一个巨大的过早优化,除非您知道在获取此Singleton时将引起大量线程争用,或者您已剖析了该应用程序并将其视为热点。


查看完整回答
反对 回复 2019-10-18
?
米琪卡哇伊

如果initialized是这样的话会奏效volatile。就像synchronized的有趣影响volatile一样,与参考数据的关系并不像我们对其他数据的说法那么重要。在写入之前,必须进行instance字段和Test对象的设置。当通过短路使用缓存的值时,读取发生在读取和通过引用到达的对象之前。拥有一个单独的标志并没有明显的区别(除了它会导致代码更加复杂)。initializedinitializeinstanceinitialized


(final不安全发布的构造函数中的字段规则有些不同。)


但是,在这种情况下,您应该很少看到该错误。首次使用时遇到麻烦的机会很小,这是一次非重复性的比赛。


代码过于复杂。您可以将其编写为:


private static final Test instance = new Test();


public static Test getInstance() {

    return instance;

}


查看完整回答
反对 回复 2019-10-18
?
桃花长相依

双重检查的锁定确实被破坏了,并且解决该问题的方法实际上比该惯用语更容易实现代码方式-只需使用静态初始化程序即可。


public class Test {

    private static final Test instance = createInstance();


    private static Test createInstance() {

        // construction logic goes here...

        return new Test();

    }


    public static Test getInstance() {

        return instance;

    }

}

可以确保在JVM首次加载类时以及在类引用可以返回到任何线程之前执行静态初始化程序,从而使其固有地具有线程安全性。


查看完整回答
反对 回复 2019-10-18

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信