繁体   English   中英

从非线程安全的方法初始化静态Java常量

[英]Initializing a static Java constant from a non-thread-safe method

让一个类定义像

  public static class Bootstrapper {

    public static final Object DEFAULT_VALUE = getDefaultValue();

    private static Object getDefaultValue() {
      if (DEFAULT_VALUE == null) {
        return createValue(); // Not thread safe
      }
      return DEFAULT_VALUE;
    }
  }

其中createValue()方法未引用DEFAULT_VALUE字段,仅在Bootstrapper类的构造函数中以其他方式调用,并且该方法也不安全。

上面的代码有什么问题(除了编程风格)? 给定类初始化的规则,大概线程安全不是问题,但是程序员需要注意的重要事项是什么?

正如Augusto解释的那样,您的代码是线程安全的。 但这相当令人费解。 简单地做到这一点在功能上是等效的,效率更高,并且更清晰:

   public static class Bootstrapper {    
     private static final Object DEFAULT_VALUE = createValue();

     public static Object getDefaultValue() {
       return DEFAULT_VALUE;
     }
   }

编辑:我也刚刚注意到,该字段是公共的,而吸气剂是私有的。 那可能应该是另一种方式。

从线程的角度来看,这是安全的,因为类加载是线程安全的,并且该值将被设置(因此getDefaultValue() )将在类加载之后但离开类加载代码之前被调用。

要回答原来的问题PNS评论以上,如果类是由两个不同的类加载器加载你有麻烦了,无论如何,与使用synchronized的关键字getDefaultValue()将创建该类的锁......因为你有2个班,每个人将完全独立。 您可以在Java语言规范的4.3.4当引用类型相同时 (对于JLS 8)中阅读此内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM