Почему нам нужно дважды вызывать инструкцию monitorexit, когда мы используем ключевое слово synchronized? - PullRequest
0 голосов
/ 12 июня 2019

Согласно спецификации JVM, параграф 3.14 Синхронизация , вызов JVM monitorexit инструкция дважды.

Интересно, зачем JVM такое поведение? Почему мы называем эту инструкцию 2 раза, а не 3, 4 или N раз?

Может быть, это как-то связано с типами синхронизирующих блокировок?

Ответы [ 2 ]

2 голосов
/ 12 июня 2019

Код не "вызывает" инструкцию monitorexit дважды. Он выполняется один раз в двух разных путях кода.

  • Первый путь к коду предназначен для нормального выхода кода из блока synchronized.
  • Второй путь кода находится в неявном пути обработки исключений для случая, когда блок завершается ненормально.

Вы можете написать байт-коды в примере как псевдокод , который выглядит следующим образом:

void onlyMe(Foo f) {
    monitorEntry(f);

    try {
        doSomething();
        monitorExit();
    } catch (Throwable any) {
        monitorExit();
        throw any;
    }
}
0 голосов
/ 12 июня 2019

Если вы посмотрите на код, он должен заканчиваться после строки 10, в которой он возвращается к оператору возврата

9   monitorexit         // Exit the monitor associated with f
10  goto 18             // Complete the method normally
13  astore_3            // In case of any throw, end up here
14  aload_2             // Push local variable 2 (f)
15  monitorexit         // Be sure to exit the monitor!
16  aload_3             // Push thrown value...
17  athrow              // ...and rethrow value to the invoker
18  return              // Return in the normal case

Но он добавляет дополнительную проверку предосторожности, если не удалось вернуть вызов снова monitorexit

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...