【发布时间】:2012-12-20 21:43:32
【问题描述】:
在“Effective Java, Second Edition”的第 71 项中,引入了双重检查习惯用法和单一检查习惯用法,用于延迟实例化实例字段。
双重检查习语
private volatile FieldType field;
FieldType getField() {
FieldType result = field;
if (result == null) {
synchronized(this) {
result == field;
if (result == null)
field = result = computeFieldValue();
}
}
return result;
}
单次检查习语
private volatile FieldType field;
FieldType getField() {
FieldType result = field;
if (result == null) {
field = result = computeFieldValue();
}
return result;
}
在复查习语 Joshua 中,result 变量用于确保 volatile field 只读取一次,从而提高性能。这我理解,但是我不明白为什么我们需要在单检查习语中使用它,因为无论如何我们只读取一次 field。
【问题讨论】:
-
双重检查已过时,因为存在多处理器环境:ibm.com/developerworks/java/library/j-dcl/index.html
-
@alfasin:这篇 IBM 文章已过时。使用 Java 5 内存模型和对 volatile 字段的保证,上述双重检查习惯用法是可以的。
-
内存模型不是这里唯一的问题,从“JIT 编译器会在这里看到优化机会......”开始阅读
-
@alfasin:这篇文章来自 2002 年。十一年前。从那以后情况发生了变化。你不认为乔什·布洛赫知道他在说什么吗?
-
@JBNizet 这是一种争论的方式吗?我应该指望别人说/写的吗?就个人而言,我喜欢了解事情背后的原因,而不是“依靠某人的话”,即使是大师......
标签: java volatile lazy-initialization effective-java