繁体   English   中英

java中的同步重新排序

[英]Synchronized reordering in java

众所周知,JVM不应该将带有同步块的语句重新排序到同步块之外。 考虑到这一点,是否允许JVM重新排序赋值y = 7以在以下代码段中的synchronized块之后发生?

x = 5;
y = 7;
synchronized (this) {
    x = 6;
}

我们知道在同步块之前的变量赋值可以重新排序以在块内发生。 所以以下内容应该是初始代码的有效重新排序:

x = 5;
synchronized (this) {
    x = 6;
    y = 7;
}

有人可能会争辩说,因为这是一个有效的排序,所以在synchronized块之后不能进行y赋值,因为它会违反规则,即在块之后不得重新排序来自同步块内的代码并推断出y 发生在结束之前同步块的。

另一方面,可能所有的排序都不等同,而且排序是实际的排序也很重要。 具体来说,如果y赋值最初是在同步块内完成的,则在块之后不会发生,否则就可能发生。

总结一下,接下来是订购第一个片段的有效排序吗?

x = 5;
synchronized (this) {
    x = 6;
}
y = 7;

JLS 17.4.5

  • 如果x和y是同一个线程的动作,并且x在程序顺序中出现在y之前,那么hb(x,y)。

...

  • 如果动作x与后续动作y同步,那么我们也有hb(x,y)。

只有在假设y的值在当前线程之外可见时,您的问题才有意义。 如果是这种情况,则这两个规则的组合要求在同步块之后不重新分配赋值。

是的,你的推理存在缺陷; 这不可能发生。

监视器输入就像一个volatile load (不完全正确,但我理解它更简单 - 插入两个障碍: LoadLoad|LoadStore )和之前的操作不能跨越该障碍。

我很确定,这是由JLS指定的,虽然我想链接到那个,但另一个答案已经做了 - 去投票吧。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM