【发布时间】:2021-06-13 15:19:14
【问题描述】:
来自《Effective Java》一书:
虽然 volatile 修饰符不执行互斥,但它保证读取该字段的任何线程都会看到最近写入的值
SO 和许多其他来源声称类似的事情。
这是真的吗?
我的意思是真的,不是一个足够接近的模型,或者只在 x86 上是真的,或者只在 Oracle JVM 中,或者不是标准英语解释的“最近编写的”的一些定义......
其他消息来源 (SO example) 表示 Java 中的 volatile 类似于 C++ 中的获取/释放语义。我认为do not 提供了报价的保证。
我发现在JLS 17.4.4 中它说“对 volatile 变量 v(第 8.3.1.4 节)的写入与任何线程对 v 的所有后续读取同步(其中“后续”是根据同步顺序定义的) )。”但我不太明白。
有相当多的来源支持和反对这一点,所以我希望答案能够说服其中许多(在任何一方)确实是错误的 - 例如参考或规范,或反例代码。
【问题讨论】:
-
“但我不太明白。”你不明白什么? JLS 是 Java 最权威的参考资料。
-
@Sweeper 不明白那句话是否意味着其他线程会立即看到该值,'synchronizes-with'和'subsequent'对我来说不够清楚
-
“这是真的吗?”是的。易失性写入发生在读取同一变量之前。
-
“有相当多的来源支持和反对这一点”请提供反对这一点的来源。
-
你需要这样读。如果负载与特定存储同步(因此可以看到它的值),则存在先发生关系。因此,可以在存储之前和加载之后对加载/存储做出某些假设。它没有说明新近度。
标签: java multithreading shared-memory volatile specifications