gpt4 book ai didi

java - 与边缘同步的编译器是否在两个方向上重新排序障碍?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:01:44 27 4
gpt4 key购买 nike

我有一个关于 Java 内存模型的问题。给定以下示例:

action 1
action 2
synchronized(monitorObject) { //acquire
action 3
} //release
action 4

acquirerelease 可以是任何同步边缘(锁定、解锁、启动线程、加入线程、检测线程中断、volatile-write、volatile-read、等等)

是否保证action 3在获取之前不能移动并且在释放之后不能移动? p>

是否保证 action 2 不能在获取之后(无论是在发布之前还是发布之后)和action 4 不能在发布之前移动(无论是在获取之前还是之后)?

对于编译器的重新排序操作,与边同步的“双向障碍”也是如此吗?


编辑 1我很担心这一点,因为如果与边缘同步不是双向重新排序障碍,编译器可以通过将锁获取转移到其他人来简单地创建死锁。

或者甚至不需要双向重新排序障碍来防止这种情况发生,因为无法将锁获取插入其他人,因为这会改变同步顺序?


编辑 2操作 1、2、3 和 4 是 JMM 定义的“线程间操作” .


编辑 3下面是一个显示重新排序如何导致死锁的示例:

x 和 y 是共享变量,syncA 和 syncB 可以被任何其他线程获取。但是使用下面的代码,就不可能出现死锁。

/* 1 */  synchronized(syncA) {
/* 2 */ x = 1;
/* 3 */ }
/* 4 */ y = 0;
/* 5 */ synchronized(syncB) {
/* 6 */ y = 1;
/* 7 */ }

但是,如果对 syncA 的获取被重新排序到 syncB block 中,这可能会导致死锁:

y = 0;
synchronized(syncB) {
y = 1;
synchronized(syncA) {
x = 1;
}
}

我认为这不是合法的编译器转换,因为它会改变同步顺序。我对这个假设是否正确? Java 内存模型 (JMM) 的哪一部分允许/不允许这样做?

最佳答案

感谢assylias链接到 this question其中包含来自 JSR-133 Cookbook 的这张图片的答案:

Reordering Rules Table

根据这张图片,EDIT 3 的编译器转换是非法的,因为它重新排序了两个 MonitorEnter

此外,此表还显示了哪些同步边是哪些类型的“重新排序障碍”以及其他操作。

谢谢你的帮助:)

关于java - 与边缘同步的编译器是否在两个方向上重新排序障碍?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26724443/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com