Что такое потоки-демоны?
Поток-демон (daemon thread) – это служебный поток, работающий в фоновом режиме для обслуживания основных (пользовательских) потоков. Ключевое свойство: JVM завершает работу, когда все не-демон потоки завершились, даже если потоки-демоны ещё работают. Демон-потоки принудительно уничтожаются при завершении JVM.
Управление демон-статусом
Пример
// Установить поток как демон (ОБЯЗАТЕЛЬНО до вызова start())
thread.setDaemon(true);
thread.start();
// Проверить, является ли поток демоном
boolean isDaemon = thread.isDaemon();
Примеры потоков-демонов в JVM
| Поток-демон | Назначение |
|---|---|
| Garbage Collector | Сборка мусора |
| Finalizer thread | Выполнение метода finalize() |
| Signal Dispatcher | Обработка сигналов ОС |
| Reference Handler | Обработка слабых/фантомных ссылок |
Важные правила
setDaemon()доstart()– вызов после старта потока выброситIllegalThreadStateException.- Наследование статуса – дочерний поток наследует демон-статус от родительского потока. Если демон-поток создаёт новый поток, тот тоже будет демоном.
- Нельзя полагаться на завершение – блоки
finallyи shutdown hooks не гарантированно выполнятся в демон-потоках при остановке JVM. Поэтому в демон-потоках нельзя выполнять критические операции (запись в файл, закрытие соединений с БД, коммит транзакций). - Основной поток – поток
mainвсегда является пользовательским потоком. Его нельзя сделать демоном (подробнее в следующем вопросе).
Пример: демон-поток завершается при окончании main
public class DaemonDemo {
public static void main(String[] args) {
Thread daemon = new Thread(() -> {
while (true) {
System.out.println("Демон работает...");
try { Thread.sleep(500); } catch (InterruptedException e) { return; }
}
});
daemon.setDaemon(true);
daemon.start();
// Основной поток работает 2 секунды и завершается
try { Thread.sleep(2000); } catch (InterruptedException e) { }
System.out.println("Main завершился — JVM останавливается, демон уничтожен");
// После завершения main JVM принудительно остановит демон-поток
}
}
Аналогия из жизни. Поток-демон – это уборщик в офисе: он работает, пока есть сотрудники. Когда последний сотрудник уходит и здание закрывается, уборщик тоже уходит, даже если не закончил уборку. Нельзя поручать уборщику запирать сейф – он может не успеть.
На собеседовании. Ключевые моменты: (1) JVM завершается, когда не осталось пользовательских потоков, демоны не учитываются; (2)
setDaemon(true)обязательно доstart(); (3) не выполняйте в демон-потоках работу, требующую гарантированного завершения. Типичный подвопрос: «Какой пример демон-потока в JVM?» – Garbage Collector.