通过阅读 Java 并发实践
我能看到:
要安全地发布对象,对象的引用和对象的状态必须同时对其他线程可见。正确构造的对象可以通过以下方式安全发布:
- 从静态初始化程序初始化对象引用
- 将对它的引用存储到 volatile 字段或 AtomicReference
- 将对它的引用存储到正确构造的对象的最终字段中
- 将对它的引用存储到一个由 锁。
但是,我对第二个成语感到困惑。由于 volatile
只能保证引用对另一个线程可见,但它不同步它引用的对象构造。那么它如何保证可变对象被正确构造,正在构造这个对象的线程被另一个线程中断了?
最佳答案
我们需要证明构造一个对象并将其分配给一个 volatile 变量发生在从该变量读取之前。
If x and y are actions of the same thread and x comes before y in program order, then hb(x, y).
因此,对象的构造发生在它被分配给一个 volatile 变量之前,从该线程的角度来看。
If an action x synchronizes-with a following action y, then we also have hb(x, y).
和:
If hb(x, y) and hb(y, z), then hb(x, z).
如果我们能证明写入 volatile 变量( Action y)与读取变量( Action z)同步,我们就可以使用happens-before 的传递性表明构造对象( Action x)happens-before 读取对象。幸运的是:
A write to a volatile variable v (§8.3.1.4) synchronizes-with all subsequent reads of v by any thread (where "subsequent" is defined according to the synchronization order).
因此,我们可以看到,以这种方式发布时,正确构造的对象对任何线程都是可见的。
关于java - volatile 保证可变对象的安全发布?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40118804/