【发布时间】:2015-12-16 18:50:18
【问题描述】:
我正在研究线程安全的单例类,我知道下面的代码不是线程安全的,因为我正在做一个双重检查锁定错误。
protected static TestSingleton instance;
private TestSingleton() {
// some code
}
public static synchronized void setup() {
if (instance == null) {
TestSingleton holder = new TestSingleton();
instance = holder;
}
}
public static TestSingleton getInstance() {
if (instance == null) {
setup();
}
return instance;
}
但我正在尝试对此进行测试,以便我可以通过编程方式证明这不是线程安全类。这是为了我的学习经验。
如何以编程方式对其进行测试并证明它不是线程安全的?
【问题讨论】:
-
您无法以编程方式证明代码是线程安全的 - 该代码实际上可能在您的 JVM/CPU 架构/操作系统的组合上始终可以正常工作。您只能希望测试会发现问题。
-
如果你在 x86/hotspot 上运行它,你可能无法让它失败。这并不意味着它是安全的,它可能会在 Java 9 或 SPARC 或... 线程(非)安全性通过应用 JLS 的规则来证明。
-
根据 Java 语言规范,请怀疑论者构造一个证明它是线程安全的。我看到的问题是调用
getInstance()的线程可能会在该值完全构造之前“看到”分配给instance的非空值。在这种情况下,读取线程永远不会遇到内存屏障。如果他们如此确信它是安全的,他们应该急于承担举证责任。 -
不,不能保证它会失败。但是,如果您遵守规则,并且能够清楚地表达它们,那么您可以确定它不会失败。为什么这甚至是一个问题?为什么不使用正确的机制?谁对这个特定的实现如此执着?为什么?
标签: java multithreading thread-safety