Глядя на Java Virtual Machine Specification и скомпилированный код сообщает нам, как блоки "synchronized" реализованы в java. Следующий код:JVM Synchronized finally Blocks
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
Первый обработчик, где я ожидаю, что это будет, но второй обработчик фактически для блока, наконец, первого обработчика, и если он ловит исключение он выполняет один и тот же обработчик. Это можно было бы плохо отразить следующим образом:
try { doSomething(); }
finally { beginTry: try { monitorexit __temp; } finally { goto beginTry; } }
Кто-нибудь знает, почему это так? Если бы это был только блок finally, второй записи в таблице не было бы там. Кроме того, я не вижу никакой возможной причины для того, чтобы снова выполнить блок finally, если он уже выбрал исключение.
Спасибо, Brandon
Думаю, вы отпустите монитор даже в случае исключения. –
Ты попытаешься выпустить монитор бесконечно много раз, даже если ясно, что ты не сможешь? Ха! – aboveyou00
Когда станет ясно, что вы не сможете? Существует важное условие, что блокировки и разблокировки всегда сбалансированы. –