多线程环境中的Java对象构造

我正在阅读这本名为“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”是局部变量还是成员变量,或者另一个线程是如何同时改变它的.

相关文章

最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤...
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不...
/*list 基本操作 * * List a=new List(); * 增 * a.add(inde...
/* * 内部类 * */ 1 class OutClass{ 2 //定义外部类的成员变...
集合的操作Iterator、Collection、Set和HashSet关系Iterator...
接口中常量的修饰关键字:public,static,final(常量)函数...