Страницы

Поиск по вопросам

воскресенье, 1 декабря 2019 г.

После метода main()

#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

Комментариев нет:

Отправить комментарий