【发布时间】:2016-03-24 13:03:34
【问题描述】:
在阅读“Java 并发实践”时,我遇到了以下问题 -
为了安全地发布对象,对象的引用和对象的状态必须同时对其他线程可见。正确构造的对象可以通过以下方式安全发布:
- 从静态初始化器初始化对象引用;
- 将对其的引用存储到 volatile 字段或 AtomicReference 中;
- 将对它的引用存储到正确构造的对象的最终字段中;或
- 将对它的引用存储到由锁适当保护的字段中。
我的问题是 - 第二点是真的吗? IE。我可以通过将对象的引用存储在易失性引用中来使其他线程可以看到对象的状态吗?如果不是,我是不是看错了以上几点?
【问题讨论】:
-
您了解“安全发布”在这种情况下的含义吗?
-
在我看来(很高兴得到纠正)这意味着阅读线程应该能够看到该对象成员的正确值(正确值 - 分配给该对象的构造函数)
-
是的,这是真的。易失性写入与任何后续易失性读取(相同变量)创建发生前的关系。在单个线程中还有一个happens-before关系。再加上 h-b 是可传递的,这意味着写入线程在存储 volatile 引用之前所做的任何事情都将对任何其他已读取 volatile 引用的线程可见。顺便说一句,任何对象的任何字段都是如此,因此您可以在任何地方进行五次非易失性写入,然后是易失性“保护”写入。
-
@AshutoshAgrawal 否。读取线程在读取 volatile 引用后,无法看到在 volatile 写入之前发生的写入尚未发生的状态。这就是为什么happens-before是传递性的很重要的原因。
标签: java multithreading memory-visibility