考虑下面的代码:什么使初始化静态初始化程序中的对象引用以安全地发布对象?
// This code safely publishes the Publishable object
public static Publishable publishable= new Publishable();
我见过这样的方式发布自定义可发布对象,我看,这是安全的。我的问题是:
- 这是安全的出版物的真正的方法吗?
- 如果1的答案是否定的,那么为什么?如果是,那么请解释为什么?
考虑下面的代码:什么使初始化静态初始化程序中的对象引用以安全地发布对象?
// This code safely publishes the Publishable object
public static Publishable publishable= new Publishable();
我见过这样的方式发布自定义可发布对象,我看,这是安全的。我的问题是:
根据JCiP:
静态初始化通过在类初始化时JVM执行[...]这个机制是保证安全地发布这样初始化的任何对象。
参考:JLS 12.4.2 - 项目9:
接着,执行任一类变量初始化和类的静态初始化,或接口的字段初始化,在文本顺序,就好像它们是一个块。
所有从静态块运行或静态初始化的代码都是线程安全的。
如果可以的话,我会让字段最终确定。
public static final Publishable publishable= new Publishable();
甚至使可发布的枚举
public enum Publishable {
INSTANCE;
}
您说过“所有代码都是从静态块运行或静态初始化是线程安全的”。但我的问题是为什么它是线程安全的? – Inquisitive
查看assylias对标准的回答。你想知道为什么它是这样定义的吗? –
是差不多的一些情况介绍会有助于 – Inquisitive
我不认为这是初始化这个对象(撇开字“安全”,这我可以解释的特别好方式以可能的方式)。
它创建一个绑定到包含类的单例,并且初始化不受控制。或者说,只要该类加载,它就会初始化。你有完全的控制权吗?
我宁愿:
虽然我同意你的主要观点,但我认为在多线程环境下的“安全发布”是非常明确的。 – assylias
@Brian +1提到延迟初始化 – Inquisitive
+1值得'可发布'最终确定它没有改变。 –
@PeterLawrey尽管我明白你的观点,但这对安全出版本身并不是必需的。 – assylias
@assylias by“class initialization”你的意思是“类加载”吗? – Inquisitive