根据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