【发布时间】:2019-09-19 13:27:57
【问题描述】:
免责声明:我不在实际生产代码中使用 DCL - 我只对学术感兴趣。
我读过以下著名文章:The "Double-Checked Locking is Broken" Declaration
问题声明(我的愿景):
// 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 执行了行 helper = new Helper();
另一个线程(thread_2)might 看到 helper 链接不为空但尚未初始化。这是因为构造函数调用可能会使用helper 链接分配重新排序
来自thread_2veiw。
但在这篇文章中提到,这种方法适用于 32 位原语。
虽然双重检查锁定习语不能用于 对对象的引用,它可以用于 32 位原始值(例如, 整数或浮点数)。请注意,它不适用于 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 位写入是原子的。
这里的局部变量是什么原因?
【问题讨论】:
标签: java multithreading concurrency volatile java-memory-model