Появился такой вопрос.
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
)?
Извиняюсь за кучу вопросов, но просто много чего непонятно и найти инфу сложно. Все одно и тоже пишут.
После метода main()
приложение обычно завершает работу, если оно работает в однопотоковом режиме. Если вы запускаете потоки, то после выхода из main()
потоки продолжают работать пока не завершатся или же будут остановлены каким нибудь способом легальным или нелегальным, как например Thread.stop()
.
Заставляет поток прекратить выполнение.
Deprecated. Этот метод по своей сути является небезопасным. Остановка
потока с помощью Thread.stop
заставляет его разблокировать все
мониторы, которые он заблокировал (как естественное следствие
неконтролируемого исключения ThreadDeath
, распространяющегося по
стеку). Если какой-либо из объектов, ранее защищенных этими
мониторами, находился в противоречивом состоянии, поврежденные объекты
становятся видимыми для других потоков, что может привести к
произвольному поведению. Многие применения stop
должны быть заменены
кодом, который просто изменяет некоторую переменную, чтобы указать,
что целевой поток должен прекратить работу. Целевой поток должен
регулярно проверять эту переменную и возвращаться из метода запуска
упорядоченным способом, если переменная указывает, что она должна
прекратиться. Если целевой поток ожидает длительные периоды (например,
при переменной условия), для прерывания ожидания следует использовать
метод interrupt
. Дополнительные сведения см. В разделе Почему
Thread.stop
, Thread.suspend
и Thread.resume
устарели ?.
Так что вам никак не завершить JVM пока вы не остановите потоки. Способ остановки потоков указан в описании устаревшего метода остановки потока. Если вы запускаете потоки по новому, т.е. через ExecutorService
то там есть метод для остановки потоков. Более подробно можно почитать здесь.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
циклом forEach беру value из Collections и добавляю их в List