1

考虑以下代码:

   // This code safely publishes the Publishable object
   public static Publishable publishable= new Publishable();

我已经看到了这种发布自定义 Publishable 对象的方式,并且我读到这是安全的。我的问题是:

  1. 真的是一种安全发布的方式吗?
  2. 如果 1 的答案是否定的,那为什么?如果是,那么还请解释为什么?
4

3 回答 3

7

根据 JCiP:

静态初始化器在类初始化时由 JVM 执行 [...] 这种机制可以保证安全地发布以这种方式初始化的任何对象。

参考:JLS 12.4.2 - 第 9 项:

接下来,按照文本顺序执行类的类变量初始化程序和静态初始化程序,或者接口的字段初始化程序,就好像它们是一个单独的块一样。

于 2012-07-03T10:22:46.177 回答
3

从静态块运行或静态初始化的所有代码都是线程安全的。

如果可以的话,我会让这个领域成为最终的。

 public static final Publishable publishable= new Publishable();

甚至使 Publishable 成为枚举

 public enum Publishable {
      INSTANCE;

 }
于 2012-07-03T10:24:11.490 回答
1

我不认为这是初始化这个对象的特别好的方法(撇开“安全”这个词,我可以用多种方式解释)。

它正在创建一个与包含类相关的单例,并且初始化不受控制。或者更确切地说,它在加载该类时立即初始化。你对此有完全的控制权吗?

我宁愿:

  1. 不要使用单例。有关使用单例的困难的更多详细信息,请参见此处。我注意到您的问题被标记为与线程相关的关键字,并且单身人士创建了他们自己的线程特定问题。
  2. 让客户类控制这个对象的初始化。您可能希望推迟此对象的初始化(想象一下,如果它突然变成一个重量级对象,在构造时执行网络调用等)。目前,上述内容对此提供的控制很少。
于 2012-07-03T10:24:32.633 回答