Код не "вызывает" инструкцию monitorexit
дважды. Он выполняется один раз в двух разных путях кода.
- Первый путь к коду предназначен для нормального выхода кода из блока
synchronized
.
- Второй путь кода находится в неявном пути обработки исключений для случая, когда блок завершается ненормально.
Вы можете написать байт-коды в примере как псевдокод , который выглядит следующим образом:
void onlyMe(Foo f) {
monitorEntry(f);
try {
doSomething();
monitorExit();
} catch (Throwable any) {
monitorExit();
throw any;
}
}