查看Java Virtual Machine Specification和编译的代码告诉我们如何在java中实现"synchronized"块。以下代码:
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块。
谢谢, 布兰登
答案 0 :(得分:2)
如果在尝试反复尝试释放监视器失败,并且在不释放监视器的情况下进行选择,则两种选择都会导致死锁;如果你继续没有释放,那么直到下次有人试图获取监视器时才会发生死锁,并且该问题可能远离最初的失败。尝试释放显示器也可能最终解决,而让显示器未发布是一个特定的灾难。所以你最好还是重试。