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

java中静态字段的双重检查锁定,java,thread-safety,static-analysis,double-checked-locking,Java,Thread Safety,Static Analysis,Double Checked Locking,我正在尝试修复双重检查锁定。但我代码中的一个小变化是字段类型是静态的,创建字段类型的方法是实例方法。 以下用于创建静态现场的变体是否有效 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() { F

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

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类习惯用法,用于静态字段-第334页。

假设您使用的是Java 5或更高版本1,上述代码是线程安全的2

方法或字段是否是静态的无关紧要,前提是:

  • 正在初始化的字段是易变的,并且
  • 执行DCL初始化的代码对任何给定字段使用相同的互斥对象
  • 前者显然是正确的。后者是正确的,因为对
    getField4()
    的所有调用都锁定了相同的
    Class
    对象

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


    我无法使该方法成为静态方法

    我不明白为什么不。它是
    私有的
    ,因此您不应该限制它是静态方法还是实例方法。它应该只影响当前类


    但是如上所述,它对习惯用法没有任何影响。

    同意——它很难看,但从技术上讲它是线程安全的(除非类型是长的——我认为在这种情况下,不能保证它是线程安全的)。如果计算方法总是解析为相同的值,并且性能相对较低,那么您也可以放弃同步,接受两个线程可能同时将字段初始化为其计算值的争用条件。谢谢。我的方法是public而不是private,我错误地将其发布为private。