2

让有一个类定义,如

  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类的构造函数中以其他方式调用,并且不是线程安全的。

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

4

2 回答 2

3

正如 Augusto 所解释的,您的代码是线程安全的。但它相当令人费解。简单地执行此操作将在功能上等效,效率更高且更清晰:

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

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

编辑:我还注意到该字段是公开的,而 getter 是私有的。应该是反过来吧。

于 2015-03-04T21:51:35.950 回答
2

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

要回答 PNS 对上述原始问题的评论,如果该类由 2 个不同的类加载器加载,那么您无论如何都会遇到麻烦,因为使用synchronized关键字 ongetDefaultValue()会在该类上创建一个锁......并且由于您有 2 个类,每个类都会完全独立。您可以在 Java 语言规范中阅读此内容,第4.3.4 节当引用类型相同时(对于 JLS 8)。

于 2015-03-04T21:43:48.917 回答