对非易失性字段的同步访问是否安全?

时间:2014-10-06 05:34:15

标签: java thread-safety volatile

我无法在任何地方找到这种特殊情况。

如果我同时从两个线程调用init(),其中一个调用是否保证会看到time不再为空? time也需要volatile吗?

它是否像join()那样是一个同步点?

private Long time;

synchronized void init() {
    if (time != null) {
        throw new IllegalStateException("Already initialised.");
    }

    this.time = System.currentTimeMillis();
}

2 个答案:

答案 0 :(得分:3)

当线程进入此synchronized方法时,它会获取对实例的implicit锁定,对其他线程可以看到它对实例的state所执行的更改,等待输入同步方法。

  

当同步方法退出时,它会自动建立一个   发生在与任何后续调用a之间的关系之前   同一对象的同步方法。 这保证了变化   所有线程都可以看到对象的状态。

文档中的最后一行清楚地提到了它。状态是volatile还是non-volatile无关紧要。

答案 1 :(得分:0)

更简单的解决方案是使用静态类初始化器。

 class TimeHolder {
       public static final long time = System.currentTimeMillis ();
 }

假设是在第一次使用类时或者在创建对象时初始化。