我正在阅读这本名为“Java Concurrency in Practice”的书,作者给出了一个不安全的对象出版物的例子.这是一个例子.
public Holder holder;
public void initialize(){
holder = new Holder(42);
}
和
public class Holder {
private int n;
public Holder(int n) { this.n = n; }
public void assertSanity() {
if (n != n)
throw new AssertionError("This statement is false.");
}
}
那么这是否意味着当其他线程甚至没有完全构造时,它可以访问一个对象?我想当一个线程A调用holder.initialize();和线程B调用holder.assertSanity();如果线程A尚未执行此操作,则不满足条件n!= n .n = n;
int n;
System.out.println(n == n); //false?
最佳答案
如果assertSanity方法在n的第一个和第二个加载之间被抢占(第一个加载将看到0而第二个加载将看到构造函数设置的值),则会出现问题.问题是基本操作是:
允许编译器/ JVM / cpu重新排序步骤#2和#3,因为没有内存屏障(最终,易失性,同步等)
从你的第二个例子来看,不清楚“n”是局部变量还是成员变量,或者另一个线程是如何同时改变它的.
原文地址:https://www.jb51.cc/java/437847.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。