1

在“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 中,结果变量用于确保 volatile字段只被读取一次,从而提高了性能。这我理解,但是我不明白为什么我们需要在单检查习语中使用它,因为无论如何我们只读取一次字段。

4

2 回答 2

5

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

于 2012-12-20T21:46:54.967 回答
0

我更喜欢以下惰性评估的实现:

@ThreadSafe
class MyClass {
    private static class MyClassHelper {
       public static final MyClass helper = new MyClass();
    }

    public static MyClass getInstance() {
        return MyClassHelper.helper;
    }
}
于 2012-12-20T21:59:59.457 回答