Как реализовать изящное завершение в Java?

Скажем, например, у меня есть приложение, работающее в терминале Linux, и я нажимаю «CTRL + C» на клавиатуре, чтобы убить процесс, который завершит программу Java.

Есть ли способ поймать этот «запрос» в моем приложении Java, чтобы я мог изящно закрыть его и освободить все ресурсы/журналы записи. У меня есть несколько разных потоков, если это имеет значение для ответа.

Я знаю, что у вас есть addShutDownHook, но, как написано в документации Java, он не вызывается при определенных обстоятельствах, например, сигнал уничтожения от «CTRL + C» в Linux... есть ли другие способы?

Runtime.getRuntime().addShutdownHook(new Thread()
{
    public void run ()
    {
        // TODO: implement graceful shutdown here.
    }
});

person Cheetah    schedule 17.05.2011    source источник


Ответы (2)


Я думаю, что отказ от ответственности существует только для kill -9, так что вы не полагаетесь на то, что хук выключения вызывается для поддержания, скажем, согласованности ваших данных.

Таким образом, если ОС разрешает процессу действовать в соответствии с сигналом, вызывается хук выключения, что довольно очевидно, если вы знаете, как работает ОС, но, возможно, не для всех Java-разработчиков.

На самом деле это очень подробно объясняется в javadoc.

Также стоит иметь в виду, что в виртуальной машине может быть зарегистрировано несколько перехватчиков выключения, поэтому ваш перехватчик может быть не САМЫМ перехватчиком выключения, а одним из нескольких.

person biziclop    schedule 17.05.2011
comment
Перехватчики выключения также не будут вызываться, если JVM остановлена ​​download.oracle.com/javase/6/docs/api/java/lang/ - person Nathan Ryan; 17.05.2011
comment
@ Натан Д. Райан Правда, я считаю, что это довольно разумно. :) Подводя итог, они не будут вызываться в ситуациях, когда вы все равно ничего не можете сделать. - person biziclop; 17.05.2011

Это работает для меня, захватывая SIGINT/Ctrl-C в Linux:

public class TestShutdownHook
{
    public static void main(final String[] args) throws InterruptedException
    {
        Runtime.getRuntime().addShutdownHook(new Thread()
        {
            @Override
            public void run()
            {
                System.out.println("Shutdown hook ran!");
            }
        });

        while (true)
        {
            Thread.sleep(1000);
        }
    }
}
person snargie    schedule 17.05.2011