Java JVM最终同步块

Java JVM最终同步块,java,multithreading,jvm,synchronized,try-finally,Java,Multithreading,Jvm,Synchronized,Try Finally,查看编译后的代码可以告诉我们如何在java中实现块。以下代码: public void testSync() { Object obj = getSomeObject(); synchronized (obj) { doSomething(); } } …大致相当于此伪代码: public void testSync() { Object obj = getSomeObject(); Object __temp = obj; monitorenter _

查看编译后的代码可以告诉我们如何在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块已经抛出异常,我看不出有任何可能的原因想要再次执行finally块

谢谢,
Brandon

如果在一次又一次尝试释放显示器失败与继续不释放显示器之间做出选择,这两种选择都会导致死锁;如果您继续操作而不释放,那么死锁不会发生,直到下次有人试图获取监视器时才会发生,而这个问题可能与最初的失败相去甚远。另外,试图释放监视器最终可能会成功,而让监视器不释放则是一场灾难。因此,您最好再试一次。

我想,即使发生异常,您也应该释放监视器。您应该尝试无限次地释放监视器,即使您显然无法释放?哈你什么时候能清楚地知道你不能?有一个重要的条件是锁和解锁总是平衡的。@TomHawtin为了记录,JVM规范中记录了
monitorexit
指令引发异常的情况:1)如果u temp为null,在这种情况下
monitorenter
将递归地引发
NullPointerException
s;2) 如果这个线程当前不是监视器的所有者,在这种情况下,递归地一次又一次地尝试“退出”监视器将毫无帮助;3) 如果监视器没有当前所有者,则会出现相同的问题。因此,如果它抛出一次异常,它将再次抛出,无限次。这些不是唯一的异常。参见第2.10节(Java SE 7的JLS)。即使是这样,在
synchronized
块之外继续执行线程也是不正确的。我想我只是心态不对。谢谢@00:它确实让你思考。实现这个东西一定很有趣,因为它必须在各种处理器上工作。是的,这样说,即使是无限循环也比不释放监视器要好。