关于其他领域的易变语义

关于其他领域的易变语义,第1张

关于其他领域的易变语义

是的,从Java 1.5开始,此代码是正确的。

无论有无波动,原子性都不是问题(对对象引用的写 *** 作是原子的),因此您可以通过任何一种方式将其从关注列表中剔除-
唯一未解决的问题是更改的可见性和排序的“正确性”。

任何对volatile变量的写 *** 作都会建立“先发生”关系(如JSR-133中所指定的新Java内存模型的关键概念),以及随后对同一变量的读取。这意味着读取线程必须对写入线程可见的所有内容具有可见性:也就是说,它必须在写入时查看所有
至少具有 其“当前”值的变量。

我们可以通过查看Java Language
Specification的17.4.5节来
详细解释这一点,特别是以下要点:

  1. “如果x和y是同一线程的动作,并且x在程序顺序中排在y之前,则hb(x,y)”(即,同一线程上的动作不能以与程序顺序不一致的方式重新排序)
  2. “在以后每次对该字段进行读取之前,都会写入一个易失字段(第8.3.1.4节)。” (这是澄清的文本,解释了易失字段的先写后读是同步点)
  3. “如果hb(x,y)和hb(y,z),则hb(x,z)”(发生之前的传递)

因此,在您的示例中:

  • 由于规则1,对“服务”(a)的写入发生在对“服务就绪”(b)的写入之前
  • 由于规则2,对“ serviceReady”(b)的写入发生在读取相同的(c)之前
  • 因此,(a)发生在(c)之前(第3条规则)

这意味着在serviceReady为true的情况下,可以保证正确设置“ service”。

您可以使用 几乎完全相同 的示例看到一些好的文章,例如在IBM
DeveloperWorks上看到的-
请参阅“新的保证波动性”:

保证在写入V时A可见的值现在对B可见。

以及由该JSR作者撰写的JSR-133
FAQ中的一个:

因此,如果读者看到v的值为true,则也可以保证看到在它之前发生的对42的写入。在旧的内存模型下,情况并非如此。如果v不易变,则编译器可以对writer中的写入进行重新排序,而读者对x的读取可能会看到0。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5429947.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-11
下一篇 2022-12-11

发表评论

登录后才能评论

评论列表(0条)

保存