'volatile'是否保证任何线程读取最近写入的值?
来自《Effective Java》一书:
虽然 volatile 修饰符不执行互斥,但它保证任何读取该字段的线程都会看到最近写入的值
SO和许多其他来源声称类似的事情。
这是真的?
我的意思是真的,不是一个足够接近的模型,或者只在 x86 上,或者只在 Oracle JVM 中,或者“最近写的”的一些定义,这不是标准的英语解释......
其他来源(SO 示例)说 Java 中的 volatile 就像 C++ 中的获取/释放语义。我认为不提供报价的保证。
我发现在JLS 17.4.4 中它说“对 volatile 变量 v 的写入(第 8.3.1.4 节)与任何线程对 v 的所有后续读取同步(其中“后续”是根据同步顺序定义的)。 ” 但我不太明白。
有很多支持和反对的消息来源,所以我希望答案能够说服其中许多(在任何一方)确实是错误的 - 例如参考或规范,或反示例代码。
回答
这是真的?
我的意思是真的,不是一个足够接近的模型,或者只在 x86 上,或者只在 Oracle JVM 中,或者“最近写的”的一些定义,这不是标准的英语解释......
是的,至少从某种意义上说,Java 的正确实现可以为您提供这种保证。
除非您使用一些奇特的、实验性的 Java 编译器/JVM (*),否则您基本上可以将其视为正确的。
从JLS 17.4.5 开始:
对 volatile 字段(第 8.3.1.4 节)的写入发生在该字段的每次后续读取之前。
(*) 正如Stephen C 指出的那样,这种没有实现语言规范中描述的内存模型语义的奇特实现不能有效地(甚至合法地)被描述为“Java”。
- I would say that an exotic Java that didn't behave according to the revised memory model in Java 5 and later is "not Java". And Oracle's lawyers (who guard the use of the Java trademarks) would agree. If a language implementation doesn't pass the JTK compliance tests, you are not allowed to call it Java (™).