#java #jvm
Появился такой вопрос. public final class Launcher { public static void main(String[] args) { // create and run many threads... } } При запуске приложения внутри main() создается и запускается куча потоков и главный поток не дожидается их завершения (нет join()). Эти потоки делают что-то тяжелое. Главный поток уже вышел из main(). Что теперь делает jvm? Я знаю, что она дожидается всех потоков не демонов. Мне интересно делает ли она что-то для своего завершения? Или просто ждет? Видел, что появляется поток DestroyJavaVM, он для чего? И что делать, если хочется после выхода из main() убить приложение? Запустить thread-таймер, который при этом демон и в нём сделать System.exit(0)? Нормальное ли это решение? Стопроцентно ли System.exit(0) убивает jvm? Или есть случаи, когда exit может повиснуть? Если, например, shutdownHook делает что-то тяжелое, то jvm будет его ждать? В каких случаях shutdownHook вообще не дергается (помимо Runtime.halt() и kill -9)? Извиняюсь за кучу вопросов, но просто много чего непонятно и найти инфу сложно. Все одно и тоже пишут.
Ответы
Ответ 1
Что теперь делает jvm? Продолжает выполнять другие потоки. Раз есть потоки - значит процесс еще работает. Мне интересно делает ли она что-то для своего завершения? Или просто ждет? Видел, что появляется поток DestroyJavaVM, он для чего? Пока есть потоки - процесс работы продолжается. DestroyJavaVM выгружает виртуальную машину из памяти. Кстати, до версии 1.2 только основной поток мог вызывать DestroyJavaVM,но в следующих версиях это ограничение было снято - теперь это может делать любой поток. И что делать, если хочется после выхода из main() убить приложение? Запустить thread-таймер, который при этом демон и в нём сделать System.exit(0)? Нормальное ли это решение? Лучше предусмотреть логику внутри других потоков, что их могут прервать (т.е. обработку interruptedException и флага isInterrupted), а из основного потока (или специально созданного) "просить" потоки завершиться. Это если нужно чтобы данные не были испорчены или сохранены в промежуточном состоянии. Обрабатывая прерывание (и флаг прерывания) изнутри потоков можно контролировать, когда именно прерваться потоку (возможно лучше доделать какой-то кусок работы - а потом выйти) Стопроцентно ли System.exit(0) убивает jvm? Или есть случаи, когда exit может повиснуть? SecurityManager может не дать так просто завершить JVM если у него метод checkExit переопределен. Если, например, shutdownHook делает что-то тяжелое, то jvm будет его ждать? Не всегда. Например если выключаете компьютер - то ОС его точно ждать не будет бесконечно - только определенное время. Поэтому туда "тяжелое" не рекомендуется засовывать - вроде IO операций или многопоточности с дедлоками ("Shutdown hooks should also finish their work quickly.") В каких случаях shutdownHook вообще не дергается (помимо Runtime.halt() и kill -9)? Ну при внутренних ошибках, которые крашат саму JVM
Комментариев нет:
Отправить комментарий