public Holder holder;
public void initialize() {
holder = new Holder(42);
}
《Java并发编程实战》上说这种不正确的发布会导致其他线程看到尚未创建完成的对象。我想请教这种情况发生的原因。是因为未使用同步产生的指令重排序吗,导致holder提前获得了未初始化的holder对象引用吗?如果是,那我是否可以使用volatile关键字来解决这个指令重排序的问题,因为这里可以看作只有写入的线程,其他都是读线程。
我希望大佬们能够详细为我解释一下。
从提供的代码来看
holder = new Holder(42);
这个语句,可以被分解为:
1.为
holder
分配内存2.初始化
Holder
对象的字段(42)3.将对象引用
holder
指向已构造的Holder
实例上述存在的问题:第3步可能会在第2步之前完成,这就导致了其他线程看到了这个对象的引用,存在空指针问题。
所以,指令重排可能导致其他线程在
holder
引用被正确初始化之前就已经看到这个对象的引用使用
volatile
后,会存在内存屏障,所以上述3个步骤会按顺序执行,就不会被打乱。