使用单一检查习语进行延迟初始化

Wil*_*ill 1 java volatile lazy-initialization effective-java

在"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;
}
Run Code Online (Sandbox Code Playgroud)

单一检查成语

private volatile FieldType field;
FieldType getField() {
  FieldType result = field;
  if (result == null) {
    field = result = computeFieldValue();
  }
  return result;
}
Run Code Online (Sandbox Code Playgroud)

在Joshua所述的复核习语中,结果变量用于确保仅读取一次volatile 字段,从而提高性能.我理解这一点,但是我不明白为什么我们在单一检查习语中需要它,因为我们只读过一次字段.

ant*_*oft 5

在单一检查成语中,如果没有结果变量,你仍然会读两次; 一次用于空检查,一次用于返回值.