Shutdown Hook – это обработчик завершения работы JVM. Действия, которые необходимо выполнить при прекращении работы программы, описываются в реализации объекта типа Thread, и передаются в Runtime.getRuntime().addShutdownHook().

При использовании обработчика нужно учитывать ряд нюансов:
1. Нет гарантии, что он будет выполнен целиком, и выполнен вообще. Хуки вызываются при нормальном завершении программы – завершении всех пользовательских потоков или вызове System.exit(). Например вызов System.halt() или получение от системы SIGKILL программа завершится незамедлительно. Это может случиться как до выполнения обработчиков, так и во время. Сигнал SIGTERM запустит обработчики, но ОС может не дождаться завершения и оборвать процесс.

2. В хуке нельзя использовать System.exit(0). Завершить работу можно ненулевым кодом, или методом System.halt(). Возврат нулевого кода после старта хуков приведет к зависанию программы.

3. Набор обработчиков задается до их старта. Когда процесс обработки начался, новый вызов addShutdownHook() вызовет исключение.

4. Нет гарантий о порядке выполнения. Если обработчиков несколько, они могут вызываться в случайном порядке, и даже параллельно, в соседних потоках. Об этом намекает и форма объявления обработчика – класс Thread.

Больше деталей об особенностях обработчиков смотрите в официальных вопросах и ответах о Shutdown Hooks API.