java - 单次和双重检查延迟初始化

标签 java multithreading thread-safety lazy-initialization

我无法理解“Effective 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;
}

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

最佳答案

双重检查锁定的要点在于,它确保computeFieldValue仅被调用一次,并且字段仅被写入一次。

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

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

关于java - 单次和双重检查延迟初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28048689/

相关文章:

c# - Mono:是否支持更改线程的优先级?

android - 我在这个简单的 android 代码中缺少什么?

java - 排序线程按照它们创建/启动的顺序运行

java - 使用通用记录器时如何禁用某些类的记录?

java - servlet 的 "display-name"有什么用?

java - 线程还是单独的对象实例?

java - Android 线程 Activity 生命周期

java - 这个 View 不受android studio的限制。即使使用推断约束我也看不到按钮

python - 在后台线程 python/pygtk 中运行计算

java - JCheckBox.isSelected() 线程安全吗?