【问题标题】:Are synchronizes-with edegs compiler re-ordering barriers in both directions?synchronizes-with edegs 编译器是否在两个方向上重新排序障碍?
【发布时间】:2014-12-30 17:04:27
【问题描述】:

我有一个关于 Java 内存模型的问题。举个例子:

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

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

是否保证action 3 在获取之前 不能移动,在发布之后 不能移动?

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

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


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

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


编辑 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 块中,这可能会导致死锁:

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

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

【问题讨论】:

  • @MinecraftShamrock 通过您的编辑,我认为您应该再次提出这个问题。显示您认为编译器可能通过“移动锁获取”“创建死锁”的位置。我开始在这里闻到 XY 问题。
  • @markspace:它可以进行一些有限的重新排序。笼统的陈述“当然,2 可能在 3 之前”是如此不准确,以至于没有用处。 (同意 X/Y 问题。)
  • @TJCrowder 但是如果它可以进行任何重新排序,那么当有人询问它是否可以重新排序时,您必须回答“是” .这是一般情况。 (我说 2 可能发生在 之后 3,而不是之前。)
  • 排序 - hb 适用于线程中的操作,例如 T1 和 T2,因此您有 (1) 个程序顺序,这意味着 HB(T1-1, T1-3), hb(T1-3, T1-5) 等 + 由于同步块,T2 和 (2) 线程间顺序相同:如果 T1 在 T2 之前在 (1) 中获取监视器,则 hb(T1-3, T2-1) 那么你需要推理关于第二个街区(T1 或 T2 都可以先锁定)。如果你假设你的重新排序可能会造成不一致(现在无法查看详细信息)。
  • 是的 - 这是相关的:stackoverflow.com/questions/19215948/… - 食谱的链接有你的答案

标签: java multithreading compiler-optimization memory-model java-memory-model


【解决方案1】:

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

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

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

感谢您的帮助:)

【讨论】:

  • @JohnVint 如果您能解释一下编辑 3 中的两行实际上会被重新排序,那就太好了。感谢您指出这一点:)
  • 当我尝试编写示例时,我注意到您在syncA 之前有syncB,所以您的答案是绝对正确的!我的回答是 syncB 在 syncA 里面,这是你没有提出的论点,对不起!
  • @JohnVint Lol xD 仍然感谢您对这个问题的批判性看法。
猜你喜欢
  • 2012-11-12
  • 2021-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-21
  • 2013-01-17
  • 2020-03-26
相关资源
最近更新 更多