繁体   English   中英

object 初始化在 Java 中是原子的吗?

[英]Is object initialization atomic in Java?

我知道myObject1 = myObject2是原子的,但是下面的代码行是原子的吗?

Object obj1 = new Object();

它实际上可以在初始化引用的中间暂停吗?

它不是原子的。 没有什么能阻止你在 Object 构造函数中sleep ,或者无限循环,或者在构造函数中抛出异常。

注意:尽管可能,但这些都是反模式,不推荐使用。

这条线不是原子的。 发生了两件事:首先,创建了新的Object (通常不是原子的),然后将这个 object 的引用分配给变量obj1 比如说,由Thread1执行的行和Thread2观察变量的 state 。 Thread2可以观察到三种状态(为简单起见,假设 object 创建本身是原子的),

  1. obj1 == null ,未创建 object
  2. obj1 == null , object 已创建,但对它的引用尚未分配给变量
  3. obj1 != null ,该行已完全执行

原子性表明Thread2可能仅观察 state 1 和 3,但必须强制执行。 使其原子化的一种方法是通过同步(在此示例中, obj1是 class 字段):

public synchronized Object getObj() {
    if (obj1 == null)
        obj1 = new Object();

    return obj1;
}

第一个调用此方法的线程将初始化该字段,进一步调用将简单地返回该变量。 由于互斥,创建null后,线程不可能观察到obj1中的null,因为不同线程的方法调用不能重叠。

引用分配是原子的。 没有条件可以部分分配引用本身(这显然会导致 VM 有时崩溃)。 它将是 null 或不为空。 在分配引用之前 object 的构造不是原子的,但是在构造过程完成之前,您将无法访问新的 object 以分配给引用。

有趣的是,参考分配可能发生在与主 memory 不同步的芯片上缓存的 memory 中。 这意味着其他线程不会立即看到分配。 有两种方法可以确保将引用分配推送到主 memory 其他线程可以立即看到它。 (1) 将引用声明为 volatile 并 (2) 将引用分配放在同步块中(退出同步块会将缓存的引用提交到主内存)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM