【发布时间】:2014-01-27 06:16:44
【问题描述】:
Wikipedia 上列出了 Java 中的 Singleton 实现之一:
public class SingletonDemo {
private static volatile SingletonDemo instance = null;
private SingletonDemo() {
}
public static SingletonDemo getInstance() {
if (instance == null) {
synchronized (SingletonDemo.class) {
if (instance == null) {
instance = new SingletonDemo();
}
}
}
return instance;
}
}
有Java Language Specification 17, paragraph 5表示
当一个对象的构造函数完成时,它被认为是完全初始化的。只有在对象完全初始化后才能看到对该对象的引用的线程可以保证看到该对象的最终字段的正确初始化值。
好的,假设我们的 SingletonDemo 类有非 final 字段。那么,并发线程将能够读取默认值而不是构造函数中指定的正确值?
【问题讨论】:
-
双重检查锁定的答案不是总是“不要使用双重检查锁定”吗?要么不起作用,要么没有帮助。
-
@user2357112 没错,但这是一个有趣的问题。我认为无论如何都应该回答。
-
不,DCL 通常非常有用,您应该小心使用它。无论如何,这是一个在许多来源中列出的常见示例。所以我只想确定它是否真的安全。这不是关于 Singleton 或 DCL,它只是关于 Java 内存模型和线程模型。
-
这与您的问题非常相关,因为它准确地解释了为什么它以前不起作用以及为什么现在起作用。
-
@WolframNyaa 该链接是回答您问题的深入解释。它是基于当前几年没有改变的内存模型编写的。您应该阅读它(直到最后)...
标签: java multithreading thread-safety final java-memory-model