Java中holder对象未初始化完全就被其他线程访问的原因?

public Holder holder;
public void initialize() {
     holder = new Holder(42);
}

《Java并发编程实战》上说这种不正确的发布会导致其他线程看到尚未创建完成的对象。我想请教这种情况发生的原因。是因为未使用同步产生的指令重排序吗,导致holder提前获得了未初始化的holder对象引用吗?如果是,那我是否可以使用volatile关键字来解决这个指令重排序的问题,因为这里可以看作只有写入的线程,其他都是读线程。

我希望大佬们能够详细为我解释一下。

阅读 403
1 个回答

从提供的代码来看
holder = new Holder(42);
这个语句,可以被分解为:
1.为 holder 分配内存
2.初始化 Holder 对象的字段(42)
3.将对象引用 holder 指向已构造的 Holder 实例
上述存在的问题:第3步可能会在第2步之前完成,这就导致了其他线程看到了这个对象的引用,存在空指针问题。
所以,指令重排可能导致其他线程在 holder 引用被正确初始化之前就已经看到这个对象的引用

使用 volatile 后,会存在内存屏障,所以上述3个步骤会按顺序执行,就不会被打乱。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏