Java 单检查和双检查延迟初始化

Java 单检查和双检查延迟初始化,java,multithreading,thread-safety,lazy-initialization,Java,Multithreading,Thread Safety,Lazy Initialization,我无法理解“有效Java”第71项中关于实例字段惰性初始化的双重检查习惯用法和单一检查习惯用法的代码: 双重检查习语 单校验成语 据我所知,我们在第一种情况下使用锁定是为了computefieldvalue()以原子方式执行。但为什么我们在第二种情况下忽略它呢?因为现在某些外来线程可能会破坏参与计算的某些值。我遗漏了什么?双重检查锁定的要点是,它确保只调用一次computeFieldValue,字段只写入一次 在某些情况下,多次调用此方法是可以接受的,这使得双重检查锁定成为一种过激行为。以下是需

我无法理解“有效Java”第71项中关于实例字段惰性初始化的双重检查习惯用法和单一检查习惯用法的代码:

双重检查习语

单校验成语


据我所知,我们在第一种情况下使用锁定是为了
computefieldvalue()
以原子方式执行。但为什么我们在第二种情况下忽略它呢?因为现在某些外来线程可能会破坏参与计算的某些值。我遗漏了什么?

双重检查锁定的要点是,它确保只调用一次
computeFieldValue
,字段只写入一次

在某些情况下,多次调用此方法是可以接受的,这使得双重检查锁定成为一种过激行为。以下是需要满足的一些条件:

  • computeFieldValue
    应该是一个纯函数,总是返回相同的值
  • 它被多次调用的风险大小是可以接受的(发生这种情况的可能性乘以其性能影响)

双重检查锁定的要点是确保只调用一次
computeFieldValue
,并且字段只写入一次

在某些情况下,多次调用此方法是可以接受的,这使得双重检查锁定成为一种过激行为。以下是需要满足的一些条件:

  • computeFieldValue
    应该是一个纯函数,总是返回相同的值
  • 它被多次调用的风险大小是可以接受的(发生这种情况的可能性乘以其性能影响)

上述示例中的第6行应为结果=字段;不是==,不是吗?上面示例中的第6行应该是result=字段;不是吗?
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;
}