是什么使得从静态初始化程序初始化对象引用以安全地发布对象?

时间:2012-07-03 10:19:01

标签: java multithreading synchronization thread-safety

请考虑以下代码:

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

我见过这种发布自定义Publishable对象的方法,我读到这是安全的。我的问题是:

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

3 个答案:

答案 0 :(得分:7)

根据JCiP:

  

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

参考:JLS 12.4.2 - 第9项:

  

接下来,按文本顺序执行类的类变量初始值设定项和静态初始值设定项,或接口的字段初始值设定项,就像它们是单个块一样。

答案 1 :(得分:3)

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

如果可以的话,我会把场地作为决赛。

 public static final Publishable publishable= new Publishable();

甚至将Publishable设为enum

 public enum Publishable {
      INSTANCE;

 }

答案 2 :(得分:1)

我认为这不是一种特别良好的方式来初始化这个对象(除了“安全”这个词,我可以用它来解释)。

它正在创建一个绑定到包含类的单例,并且初始化不受控制。或者更确切地说,只要加载该类,它就会初始化。你完全控制了吗?

我宁愿:

  1. 不使用单身人士。有关使用单身人士的困难的详细信息,请参阅here。我注意到你的问题用与线程相关的关键字标记,而单身人士在线程创建atheir本身的特殊问题。
  2. 让客户端类控制此对象的初始化。您可能希望推迟初始化此对象(想象一下,如果它突然变成一个重量级对象,在构造时执行网络调用等)。目前上面提供的控制很少。