双重检查 java 中静态字段的锁定

Double checked locking for static fields in java

我正在尝试使用 Bloch's effective java recommendation 修复双重检查锁定。但是我的代码中的一个小变化是字段类型是静态的,创建字段类型的方法是实例方法。 以下用于创建静态字段的变体是否有效?

private static volatile FieldType field4;

// NOTE: The code for this method in the first printing had a serious error (see errata for details)!
public FieldType getField4() {
    FieldType result = field4;
    if (result != null)    // First check (no locking)
        return result;
    
    synchronized(Initialization.class) {
        if (field4 == null) // Second check (with locking)
            field4 = computeFieldValue();
        return field4;
    }
}

我无法将方法设为静态方法 // Lazy initialization holder class 静态字段的习惯用法 - 第 334 页。

假设你使用的是Java5或更高版本1,以上代码是线程安全的2.

方法或字段是static并不重要,前提是:

  1. 正在初始化的字段是 volatile 并且,
  2. 执行 DCL 初始化的代码对任何给定字段使用相同的互斥对象。

前者显然是正确的。后者是正确的,因为对 getField4() 的所有调用都锁定了同一个 Class 对象。

1 - 在 Java5 之前,volatile 的指定语义不足以保证代码是线程安全的。
2 - 线程安全但丑陋。最好避免使用 DCL 习语并使用其他替代方法之一。


I cannot make the method static method ...

我不明白为什么不。它是 private 所以你不应该被限制它是静态方法还是实例方法。它应该只影响当前的 class.

但是如上所述,它对成语没有任何影响。