[英]Why DCl without volatile is valid for primitives?
Discalimer:我不在实际生产代码中使用 DCl - 我只有学术兴趣。
我读过以下著名文章: “双重检查锁定被破坏”声明
问题声明(我的愿景):
// Correct multithreaded version
class Foo {
private Helper helper = null;
public synchronized Helper getHelper() {
if (helper == null)
helper = new Helper();
return helper;
}
// other functions and members...
}
假设thread_1执行了 line helper = new Helper();
另一个线程( thread_2
) might
看到helper
链接不是 null,但它尚未初始化。 发生这种情况是因为构造函数调用可能会使用来自thread_2
veiw 的helper
链接分配进行重新排序。
但是在这篇文章中提到,这种方法适用于 32 位原语。
尽管双重检查锁定习惯用法不能用于对对象的引用,但它可以用于 32 位原始值(例如,int 或 float)。 请注意,它不适用于 long 或 double,因为不保证 64 位原语的非同步读/写是原子的。
// Correct Double-Checked Locking for 32-bit primitives
class Foo {
private int cachedHashCode = 0;
public int hashCode() {
int h = cachedHashCode;
if (h == 0)
synchronized(this) {
if (cachedHashCode != 0) return cachedHashCode;
h = computeHashCode();
cachedHashCode = h;
}
return h;
}
// other functions and members...
}
请解释一下为什么它有效? 我知道 32 位写入是原子的。
这里局部变量的原因是什么?
The essence of the "DCL is broken" trope is that, using DCL to initialize a singleton object, a thread could see the reference to the object before it sees the object in a fully initialized state. DCL 充分同步了引用 singleton 的有效最终全局变量,但无法同步全局引用的 singleton object。
在您的示例中,只有全局变量。 没有“它所指的对象”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.