Gymterview
junior

Что такое потоки-демоны?

Поток-демон (daemon thread) – это служебный поток, работающий в фоновом режиме для обслуживания основных (пользовательских) потоков. Ключевое свойство: JVM завершает работу, когда все не-демон потоки завершились, даже если потоки-демоны ещё работают. Демон-потоки принудительно уничтожаются при завершении JVM.

Управление демон-статусом

Пример
// Установить поток как демон (ОБЯЗАТЕЛЬНО до вызова start())
thread.setDaemon(true);
thread.start();

// Проверить, является ли поток демоном
boolean isDaemon = thread.isDaemon();

Примеры потоков-демонов в JVM

Поток-демон Назначение
Garbage Collector Сборка мусора
Finalizer thread Выполнение метода finalize()
Signal Dispatcher Обработка сигналов ОС
Reference Handler Обработка слабых/фантомных ссылок

Важные правила

  1. setDaemon() до start() – вызов после старта потока выбросит IllegalThreadStateException.
  2. Наследование статуса – дочерний поток наследует демон-статус от родительского потока. Если демон-поток создаёт новый поток, тот тоже будет демоном.
  3. Нельзя полагаться на завершение – блоки finally и shutdown hooks не гарантированно выполнятся в демон-потоках при остановке JVM. Поэтому в демон-потоках нельзя выполнять критические операции (запись в файл, закрытие соединений с БД, коммит транзакций).
  4. Основной поток – поток 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.