7

查看Java 虚拟机规范和编译代码告诉我们如何在 java 中实现“同步”块。以下代码:

public void testSync()
{
    Object obj = getSomeObject();
    synchronized (obj) { doSomething(); }
}

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

public void testSync()
{
    Object obj = getSomeObject();
    Object __temp = obj;
    monitorenter __temp;
    try { doSomething(); }
    finally { monitorexit __temp; }
}

...除了一个例外。

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

  Exception table:
     from    to  target type
        12    20    23   any
        23    25    23   any

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

try { doSomething(); }
finally { beginTry: try { monitorexit __temp; } finally { goto beginTry; } }

有人知道这是为什么吗?如果它只是 finally 块,则表中的第二个条目将不存在。此外,如果 finally 块已经抛出异常,我看不出有任何可能的原因要再次执行它。

谢谢,布兰登

4

1 回答 1

2

如果在反复尝试释放监视器失败和继续不释放监视器之间进行选择,两种选择都会导致死锁;只是如果您在不释放的情况下继续进行,那么直到下一次尝试获取监视器时才会发生死锁,并且该问题可能与最初的失败相去甚远。同样尝试释放监视器可能最终会奏效,而让监视器未释放是一定的灾难。所以你最好重试。

于 2013-02-27T20:26:03.923 回答