众所周知,JVM不应该将带有同步块的语句重新排序到同步块之外。考虑到这一点,是否允许JVM将赋值y = 7
重新排序到以下代码片段中的synchronized
块之后?
x = 5;
y = 7;
synchronized (this) {
x = 6;
}
我们知道,同步块之前的变量赋值可以重新排序,以便在块内发生。因此,以下代码应该是对初始代码的有效重新排序:
x = 5;
synchronized (this) {
x = 6;
y = 7;
}
有人可能会争辩说,因为这是一个有效的排序,所以y
赋值不能发生在synchronized
块之后,因为它会违反来自同步块内的代码不能被重新排序为发生在块之后的规则,并推断y
发生在同步块的结束之前。
另一方面,可能并不是所有的排序都是等价的,哪种排序是实际的排序很重要。具体地说,如果y
赋值最初是在synchronized块中完成的,那么它不可能在该块之后发生,否则它就会发生。
总而言之,下一次排序是第一个片段的有效排序吗?
x = 5;
synchronized (this) {
x = 6;
}
y = 7;
发布于 2018-10-15 04:43:00
是的,你的推理是有缺陷的;这是不可能发生的。
监视器enter类似于volatile load
(不完全正确,但我理解它更简单-将插入两个障碍:LoadLoad|LoadStore
)和之前不能跨越该障碍的操作。
我很确定,这是由JLS
指定的,虽然我想链接到它,但另一个答案已经做到了--去投票吧。
https://stackoverflow.com/questions/52806674
复制相似问题