Если я наберу Ctrl-C в командной строке, будет ли выполняться блок finally в Java?

Я запускаю свое Java-приложение в cmd.exe в Windows. Если я принудительно остановлю процесс, нажав Ctrl-C, а код в этот момент выполнялся в блоке try, будет ли по-прежнему выполняться блок finally?

По моим тестам кажется, что да, выполняется.


person Hesey    schedule 06.02.2011    source источник


Ответы (4)


Хотя ваш код finally мог быть выполнен на вашем компьютере с Windows (я не смог воспроизвести его с Linux), согласно эта документация, наконец:

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

Поэтому я бы не стал использовать блок finally, чтобы убедиться, что часть кода выполняется, даже если пользователь попытается преждевременно выйти. Если вам это нужно, вы можете использовать, например, Адриан Петреску упоминается, Перехватчики отключения

person Zach L    schedule 06.02.2011
comment
Суть здесь в том, что после SIGTERM блок finally может выполниться, но это не гарантируется. Поскольку нет никакой гарантии, вы не должны полагаться на это. - person Cameron Skinner; 06.02.2011

Правильный способ гарантировать, что некоторый код запускается в ответ на сигнал операционной системы (что и делает Ctrl-C, он отправляет SIGINT), — это зарегистрировать «shutdownHook». Вот вопрос StackOverflow о его обработке, а вот статья и многое другое подробности об обработке сигналов JVM, чем вы, возможно, когда-либо захотите узнать.

person Adrian Petrescu    schedule 06.02.2011

В моем тесте на Windows 7, Sun Java 1.6 блок finally не выполнялся, если я нажимал Ctrl-C во время этого блока try.

public static void main(String[] args) {
    try {
        for (int i = 0; i < 1000; i++) {
            System.out.println(i);
        }
    }
    finally {
        System.out.println("finally");
    }
}
person Joe Daley    schedule 06.02.2011

В зависимости от реализации ОС обычно sigkills предназначены для немедленной остановки приложений. В этой ситуации нежелательно полагаться на блок finally для выполнения; это может быть в некоторых ситуациях, но в целом это будет / не должно. Документация java.lang.Runtime дополнительно поддерживает это:

In rare circumstances the virtual machine may abort, that is, stop running without shutting down cleanly. This occurs when the virtual machine is terminated externally, for example with the SIGKILL signal on Unix or the TerminateProcess call on Microsoft Windows. The virtual machine may also abort if a native method goes awry by, for example, corrupting internal data structures or attempting to access nonexistent memory. If the virtual machine aborts then no guarantee can be made about whether or not any shutdown hooks will be run.

person nawazish-stackoverflow    schedule 21.12.2017