在“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所述的复核习语中,结果变量用于确保仅读取一次易失性字段,从而提高性能。我理解这一点,但是我不明白为什么我们在单一检查习语中需要它,因为我们只读过 field 。
答案 0 :(得分:5)
在单一检查成语中,如果没有结果变量,你仍然会读两遍;一次用于空检查,一次用于返回值。
答案 1 :(得分:1)
我更喜欢以下懒惰评估的实现:
@ThreadSafe
class MyClass {
private static class MyClassHelper {
public static final MyClass helper = new MyClass();
}
public static MyClass getInstance() {
return MyClassHelper.helper;
}
}