根据 Java Concurrency in Action 如果我们有以下类:
public class Wrapper {
private int num;
public Wrapper(int num) {
this.num = num;
}
public void assertCorrectness() {
if (num != num)
throw new AssertionError("This is false");
}
}
Run Code Online (Sandbox Code Playgroud)
并且我们初始化此类的实例并以非安全方式发布它(例如通过简单的公共字段),那么如果从另一个线程调用,assertCorrectness() 可能确实会抛出 AssertionError。换句话说,这意味着另一个线程可能会看到对该实例的最新引用,但实例本身的状态可能已过时(因此线程可以看到对象存在,但它处于部分构造/不一致的状态)。
另一方面,据说通过易失性引用发布此类的实例被认为是安全的。然而,我的理解是,易失性只是保证任何线程总是会看到引用的最新版本,但看不到被引用的对象的状态。因此,我们可以确定,如果一个线程将 Wrapper 类的新实例分配给 易失性字段,那么所有其他线程都会看到引用已更新。但是是否存在他们仍然会看到处于不一致/部分构造状态的对象的风险?