为什么当我们使用"同步"关键字时,我们需要调用"监视器退出"指令两次?



根据JVM规范第3.14段同步,JVM调用监视器退出指令两次。

我想知道为什么JVM需要这样的行为?为什么我们调用此指令 2 次,而不是 3 次、4 次或 N 次?

可能是它与同步锁的类型有某种联系?

代码不会"调用"monitorexit指令两次。 它在两个不同的代码路径上执行一次。

  • 第一个代码路径用于synchronized块中的代码正常退出的情况。
  • 第二个代码路径位于块异常终止情况的隐式异常处理路径中。

您可以将示例中的字节码编写为伪代码,如下所示:

void onlyMe(Foo f) {
    monitorEntry(f);
    try {
        doSomething();
        monitorExit();
    } catch (Throwable any) {
        monitorExit();
        throw any;
    }
}
<小时 />

如果您想了解更多信息,请查看此旧问题:

  • 如何正确退出字节码中的监视器?

如果你看一下代码,它应该在第 10 行之后结束,在那里它 goto return 语句

9   monitorexit         // Exit the monitor associated with f
10  goto 18             // Complete the method normally
13  astore_3            // In case of any throw, end up here
14  aload_2             // Push local variable 2 (f)
15  monitorexit         // Be sure to exit the monitor!
16  aload_3             // Push thrown value...
17  athrow              // ...and rethrow value to the invoker
18  return              // Return in the normal case

但它增加了一个额外的谨慎检查,如果未能再次返回呼叫monitorexit

相关内容

最新更新