单例DCL损坏是什么意思? [英] What does it mean that singleton DCL broken?

查看:144
本文介绍了单例DCL损坏是什么意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

阅读了数十篇有关DCL的文章之后.我觉得我应该在没有volatile的情况下使用这个概念. 最近,我重新阅读了基础知识,然后又有了另一种看法
让我们研究单例代码清单:

After reading dozens of articles about DCL. I feel that I should not use this concept without volatile.If I will not lead this technique my code will not thread save and very very bad according one hundreed different reasons.
Recently I reread basics Happens Before and I have a bit another view
Lets research singleton code listing:

public class Singleton{
    private static Something instance = null;
    public static Singleton getInstance() {
        if (instance == null) { // point 1
            synchronized (Singleton.class) {
                if (instance == null)
                    instance = new Something();
            }
        }
        return instance;  //point 2
    }

}

我们仅在synchronized (Something.class) {

因此,我们将在使用相同监视器的同步部分内看到实际值.是我们的情况.

thus we will see actual value inside synchronized section which uses same monitor. It is our case.

因此,我现在怀疑这不是有效的方法,但是线程安全.

Thus now I have suspicion that this is not effective but it thread safe.

我说得对吗?

只有一个问题:

if (instance == null) {可以在实际分配instance = new Something();

但是我仍然绝对确定此代码不允许创建2个单例实例

But I still absolutely sure that this code doesn't allow to create 2 singleton instances

我阅读了更多内容,看起来如果在point 1中我们读取了非null值,则point 2处的return instance可能返回null;

I read a bit more and looks like if in point 1 we read non-null value, return instance at point 2 could return null;

推荐答案

示例中的问题不是可能创建两个实例.确实只有一个实例可以创建.真正的问题是,在使用多线程访问此方法时,其他线程可能会开始使用部分构造的instance (1) (2).

The problem in your example is not in possible creating of two instances. That's true that only one instance will be created. Real problem is that on multiple thread access to this method, other thread can start using partially constructed version of instance (1)(2).

因此,instance变量应明确定义为volatile(在代码块中丢失),否则,您应关注此变量的值的新鲜度".

So, instance variable should be definitely defined as volatile (which is missed in your code block), otherwise you should concern about "freshness" of this variable's value.

因为该字段已经初始化,所以没有锁定,因此 至关重要的是,该字段必须声明为易失性(条款66)[J. Bloch,有效的Java",条款71]

Because there is no locking if the field is already initialized, it is critical that the field be declared volatile (Item 66) [J. Bloch, "Effective Java", Item 71]

所以:

private static volatile Something instance;

(顺便说一句,明确分配null值是多余的).

(BTW, explicitly assigning null value is redundant).

如果没有"volatile",为什么它不起作用这里:

Why it doesn't work without "volatile" is good explained here:

最明显的原因是行不通 初始化Helper对象,并且可以写入helper字段 完成或感觉混乱

The most obvious reason it doesn't work it that the writes that initialize the Helper object and the write to the helper field can be done or perceived out of order

这篇关于单例DCL损坏是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆