JVM同步最终块

abo*_*u00 7 java multithreading jvm synchronized try-finally

查看Java虚拟机规范和编译代码,告诉我们如何在java中实现"synchronized"块.以下代码:

public void testSync()
{
    Object obj = getSomeObject();
    synchronized (obj) { doSomething(); }
}
Run Code Online (Sandbox Code Playgroud)

...大致相当于这个伪代码:

public void testSync()
{
    Object obj = getSomeObject();
    Object __temp = obj;
    monitorenter __temp;
    try { doSomething(); }
    finally { monitorexit __temp; }
}
Run Code Online (Sandbox Code Playgroud)

......有一个例外.

出于某种原因,异常表显示两个finally处理程序.例如:

  Exception table:
     from    to  target type
        12    20    23   any
        23    25    23   any
Run Code Online (Sandbox Code Playgroud)

第一个处理程序是我期望的,但第二个处理程序实际上是第一个处理程序的finally块,如果它捕获异常,它会执行相同的处理程序.您可以通过以下方式将其可视化:

try { doSomething(); }
finally { beginTry: try { monitorexit __temp; } finally { goto beginTry; } }
Run Code Online (Sandbox Code Playgroud)

有谁知道这是为什么?如果它只是finally块,则表中的第二个条目不会出现.此外,如果它已经被抛出异常,我看不出任何可能的理由想要再次执行finally块.

谢谢,布兰登

Nat*_*hes 2

如果要在一遍又一遍地尝试释放监视器失败和继续而不释放监视器之间进行选择,这两种选择都会导致死锁。只是如果您继续而不释放,那么直到下一次尝试获取监视器时才会发生死锁,并且该问题可能远离最初的失败。尝试释放监视器最终可能会成功,而让监视器不被释放则是一场灾难。所以你最好重试。