加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

在Java中如何理解“发生之前的一致性是不够的”

发布时间:2020-12-14 05:27:17 所属栏目:Java 来源:网络整理
导读:在 chapter 17 of Java language specification年,有一个部分解释为什么“前后一致性不足”.这里是例子: At first,x = y = 0Thread 1 | Thread 2r1 = x; | r2 = y; if (r1 != 0) y = 1; | if (r2 != 0) x = 1; 这里有一个可能的执行痕迹: r1 = x; // sees
在 chapter 17 of Java language specification年,有一个部分解释为什么“前后一致性不足”.这里是例子:
At first,x = y = 0
Thread 1            | Thread 2
r1 = x;             | r2 = y; 
if (r1 != 0) y = 1; | if (r2 != 0) x = 1;

这里有一个可能的执行痕迹:

r1 = x;  // sees write of x = 1
y = 1;
r2 = y;  // sees write of y = 1
x = 1;

怎么会这样呢?我感到困惑的是,当第一个动作看到x = 1时,这并不意味着条件r2!= 0成为真,因此y已被分配给1.但是按照这个顺序,y = 1在r1 = x之后.我在哪里弄错了例子?我该如何正确解释这个例子?

解决方法

我相信这个例子在Java规范中的观点是Hans Boehm等人写在 Outlawing Ghosts年,它指出了一些当代语言的记忆模型(Java,C 11,甚至C 14,仍然解决,但没有解决这个问题)的缺陷.

要点是这样:程序按照书面的规则被语言的规则正确同步. (在C中,如果你使用原子变量和memory_order_relaxed到处都是如此)但是,仍然不会发生意外行为.说明Boehm:机器可以推测x的值,例如x为1,然后执行结果分支??,稍后(大概是当内存终于响应时)验证猜测是否为真.确实发现猜测,因为在另一个线程确实存储x = 1,机器继续并且不回滚推测的执行.

更糟糕的是,CPU真的可以推测任何价值存在.考虑这个修改的例子:

r1 = x                     |  r2 = y
if (r1 != 0) y = r1        |  if (r2 != 0) x = r2

在这种情况下,由于相同的原因,x和y可能会以任何值结束.机器可以推测价值是什么,然后推测继续执行这个假设,后来发现它的猜测是真实的,在谚语的自我实现的预言.

这可能令人放心,目前没有真正的硬件表现如此.但关键是当代语言的记忆模式并不能阻止这种行为.您引用的部分是Java尝试说:“看,我们需要在一致性之前发生,但这个另外奇怪的事情在这里仍然不应该发生”.在非规范性说明1.10 / 25中,C 14对这个问题也有同样的含糊的意见.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读