请考虑下面的代码片段。
public class Visibility {
private volatile SomeData data;
public static class SomeData {
private int number;
public SomeData(int number) {
this.number = number;
}
public int getNumber() {
return number;
}
}
public void initialize() {
data = new SomeData(42);
}
public SomeData getData() {
return data;
}
}如果number字段是最终的,任何看到data引用的线程都不是null (在其他线程称为initialize之后),也保证将number字段值作为42。
对于非最终领域,我们有同样的保证吗?换句话说,某些线程是否可以观察到非空的data引用,但是number字段是0。
提前感谢!
发布于 2018-04-13 04:20:29
某些线程不可能观察到非空数据引用,而是字段为0,这是不可能的。
请参阅易失性的文档:
这意味着对易失性变量的更改对其他线程总是可见的。此外,它还意味着当线程读取易失性变量时,它不仅会看到对易失性的最新更改,而且还会看到导致更改的代码的副作用。
因此,当您得到一个非空data时,它必须已成功启动,number必须为非零。
发布于 2018-04-12 15:11:10
通常,是的,如果字段没有以安全的方式发布,则可以看到字段处于部分构造的状态。在您的问题的特定情况下,volatile关键字是一种令人满意的安全发布形式。根据Java并发在实践中的应用
为了安全地发布对象,对对象和对象状态的引用必须同时对其他线程可见。通过以下方法可以安全地发布构造正确的对象:
有关更多信息,请参见以下内容:
https://stackoverflow.com/questions/49799855
复制相似问题