【问题标题】:Static variable initialization during declaration in multi-threading多线程声明期间的静态变量初始化
【发布时间】:2015-12-09 15:30:00
【问题描述】:

我想将以下代码添加到我的班级:

static private final ILogic_P logicInstanceI =
    (ILogic_P)Factory.CreateAnon("some.path.ILogic_P" + (SomeClass.isIMDB() ? "1" : "2"));

public static ILogic_P getLogicInstanceI(){
    return logicInstanceI;
}

我不知道静态变量的初始化是否是线程安全的。 有没有可能两个线程同时尝试初始化这个属性?

【问题讨论】:

  • 静态实例在类加载期间被初始化,并且是每个类实例的“同步”。所以是的,这是线程安全的。
  • 我不喜欢那个副本。呸。
  • 谢谢,现在清楚了。

标签: java multithreading static-variables


【解决方案1】:

答案由Java Language Specification §12.4.2给出:

因为 Java 编程语言是多线程的,所以类或接口的初始化需要仔细同步,因为其他线程可能同时尝试初始化同一个类或接口。还有一种可能性是,作为该类或接口初始化的一部分,可以递归地请求类或接口的初始化;例如,A 类中的变量初始化器可能会调用不相关类B 的方法,而后者又可能调用A 类的方法。 Java 虚拟机的实现负责通过使用以下过程来处理同步和递归初始化。 […]

注意最后一句以“Java 虚拟机的实现负责照顾 ...”开头的句子

所以在类初始化的情况下你不负责同步,给static变量赋初始值是类初始化的一部分,在§8.3.2中指定:

8.3.2。字段初始化

如果字段声明中的声明器具有变量初始值设定项,则声明器具有对已声明变量进行赋值(第 15.26 节)的语义。

如果声明器用于类变量(即static 字段),则以下规则适用于其初始化器:

  • 在运行时,初始化器被评估并且赋值只执行一次,当类被初始化时(第 12.4.2 节)。

【讨论】:

  • 当然,这确实假设 JVM 的同步没有任何错误。 (通常是一个安全的假设,但并不是说编译器和虚拟机就可以保证没有错误。)总会有一些极端情况,在错误报告出现之前没有人最终测试。
  • @JAB:如果你假设一个有缺陷的 JVM,你无论如何都会迷路。谁说synchronized 或任何你用于线程安全的东西都能正常工作?但是正确的类初始化是 JVM 开发人员必须关心的最关键的事情之一……
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-20
相关资源
最近更新 更多