有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

使用单次检查习惯用法的java惰性初始化

在“有效Java,第二版”的第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字段只读取一次,从而提高了性能。我明白这一点,但是我不明白为什么我们需要在单次检查习惯用法中使用它,因为我们无论如何只读取一次字段


共 (2) 个答案

  1. # 1 楼答案

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

    @ThreadSafe
    class MyClass {
        private static class MyClassHelper {
           public static final MyClass helper = new MyClass();
        }
    
        public static MyClass getInstance() {
            return MyClassHelper.helper;
        }
    }
    
  2. # 2 楼答案

    在单次检查习惯用法中,如果没有结果变量,您仍将读取它两次;一次用于空检查,一次用于返回值