Хуки завершения работы не должны ожидать, что другие службы будут в известном состоянии (например, поток обработки событий пользовательского интерфейса и т. Д.), Потому что приложение было запрошено для закрытия.Написание перехвата отключения, который пытается обновить что-то, что не находится на 100% под контролем перехватчика, может привести к этому и другому поведению, которое будет трудно устранить.
Метод addShutdownHook
специально упоминает этот случайи предупреждает, что вы не должны пытаться выполнять подобные действия, поскольку это может легко привести к непредвиденным последствиям, таким как блокировка, которую вы наблюдали.
С документация :
Завершающие хуки запускаются в непростое время в жизненном цикле виртуальной машины и поэтому должны кодироваться с защитой.В частности, они должны быть написаны так, чтобы они были поточно-ориентированными и, по возможности, избегали взаимоблокировок.Они также не должны слепо полагаться на сервисы, которые могли зарегистрировать свои собственные ловушки отключения и, следовательно, могут сами в процессе выключения.
В этом случае, поскольку Swing является многопоточной системой пользовательского интерфейса, котораяВы не контролируете, я бы порекомендовал не пытаться изменить что-либо в пользовательском интерфейсе на этапе завершения вашей программы.Это может привести к странным, непредсказуемым, а иногда и неповторимым ситуациям, которые могут варьироваться от одного запуска к следующему или от одного компьютера к другому, в зависимости от того, как запланировано отключение потоков.То, как и когда другой поток прекращает свою работу, не должно происходить линейным, предсказуемым образом.Таким образом, любой код, который вы пишете в многопоточной программе, которая полагается на то, что другой поток находится в определенном состоянии в определенное время (если только эти потоки не сообщаются друг с другом об их состоянии), откроет вам возможность такого родапроблемы.
Я полагаю, что мой следующий вопрос будет: "Почему вы хотите / должны изменить JLabel во время процесса выключения?"Если вы хотите изменить состояние чего-либо перед выключением, то лучший способ сделать это - перехватить ввод с клавиатуры как обычное событие (предотвращающее закрытие приложения), измените текст JLabel,а затем запустите завершение работы приложения самостоятельно с помощью вызова System.runFinalization () и / или System.ext (int)