Как обеспечить выполнение фрагмента кода перед выходом из Java-приложения

Я использую лицензированный API, у которого есть метод получения/освобождения объекта лицензии с сервера лицензий, который имеет конечное количество лицензий. В начале моего приложения я вызываю метод для получения лицензии, но я хочу убедиться, что он будет выпущен, даже если моя программа внезапно завершится/вылетит (исключения, SIGTERM и т. д.). Является ли крюк выключения лучшим способом решить эту проблему?


person fo_x86    schedule 06.12.2012    source источник
comment
Вы имели в виду пункт finally?   -  person Paul Vargas    schedule 07.12.2012


Ответы (4)


@thedan прав насчет жестких сбоев JVM. Если JVM сильно выйдет из строя или получит SIGKILL, у нее не будет возможности запустить что-либо до выхода. Вы ничего не можете сделать, чтобы исправить это в Java в этом сценарии. (Но такая же ситуация и в других языках...)

Однако, если JVM выполняет упорядоченное завершение работы в ответ на завершение всех потоков, отличных от dameon, вызов System.exit(), получение SIGINT и т. д., то JVM попытается запустить перехватчики выключения. Дополнительную информацию о механизмах перехватчиков завершения работы Java см. в разделе Вопросы и ответы. и javadocs .

Подход finally также является вариантом, но он работает только в том случае, если рассматриваемый поток завершается до выхода из JVM. Этого не произойдет, если вызывается System.exit() или JVM завершается сигналом. Хуки выключения работают в большем количестве ситуаций.

(На мой взгляд, finally действительно предназначен для выполнения очистки в одном потоке, а не во всем приложении. Однако, если ваше приложение состоит только из одного потока... или если у него есть главный поток, который отвечает за упорядоченное завершение работы... тогда finally может служить для очистки приложения.)


Реальное решение состоит в том, чтобы настроить лицензированный API так, чтобы менеджер лицензий мог определить, когда экземпляр приложения, использующий лицензию, исчезает, не освобождая его. Возможно ли это, зависит от менеджера лицензий.

person Stephen C    schedule 06.12.2012

Если программа завершается из-за сбоя JVM, вы не можете полагаться на то, что что-либо вызывается.

Если программа завершается из-за исключения, которое не связано с JVM, вы должны иметь возможность обернуть все в блок try/catch/finally. Любой код в блоке finally будет гарантированно запущен до выхода вашего кода.

person thedan    schedule 06.12.2012


вы достигаете этого, никогда не вызывая System.exit(). В main() вы создаете «последнюю линию защиты» с помощью

 try {
    startApp();
 } catch (Exception ex) {
      // do some logging
 } finally {
    releaseLicense();
 }
person AlexWien    schedule 06.12.2012