首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么叫单例DCL坏了?

什么叫单例DCL坏了?
EN

Stack Overflow用户
提问于 2017-01-31 11:21:40
回答 1查看 441关注 0票数 1

在阅读了几十篇关于DCL的文章之后。我觉得如果没有volatile.If,我就不应该使用这个概念,我不会领导这种技术,我的代码不会线程保存,而且非常糟糕,因为有一百个不同的原因。

最近,我重读了以前发生的一些基本知识,我有了另一种看法。

让我们研究一下单例代码清单:

代码语言:javascript
复制
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) {中更改实例

因此,我们将在使用相同监视器的同步部分中看到实际值。这是我们的案子。

因此,现在我怀疑这不是有效的,而是线程安全。

我说的对吗?

只关注一个问题:

if (instance == null) {可以在实际赋值instance = new Something();之前查看非空值吗?

但我仍然绝对确信这段代码不允许创建2个单例实例

附注:

我读得更多一些,如果我们在point 1中读取非空值,return instance at point 2可以返回null;

EN

回答 1

Stack Overflow用户

发布于 2017-01-31 11:30:56

在您的示例中,在可能创建两个实例方面的问题不是。这是事实,只有一个实例将被创建。真正的问题是,在多个线程访问此方法时,其他线程可以开始使用部分构造的instance (1)(2)版本。

因此,instance变量应该明确地定义为volatile (这在代码块中是遗漏的),否则您应该关注这个变量的值的“新鲜度”。

因为如果字段已经初始化,则没有锁定,因此必须将字段声明为易失性(项目66),J. Bloch,“有效Java",项目71

所以:

代码语言:javascript
复制
private static volatile Something instance;

(顺便说一句,显式分配null值是多余的)。

这里很好地解释了为什么没有“易失性”就不能工作

它不能工作的最明显的原因是初始化Helper对象的写操作和对助手字段的写入可以被执行或被认为是无序的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41956290

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档