스레드는 사용자(user) 스레드와 데몬(daemon) 스레드 2가지 종류로 구분할 수 있다.
JVM은 데몬 스레드의 실행 완료를 기다리지 않고 종료.
데몬 스레드가 아닌 모든 스레드가 종료되면, 자바 프로그램도 종료
(컴퓨터 과학에서 데몬이란, 사용자에게 직접적으로 보이지 않으면서 시스템의 백그라운드에서 작업을 수행하는 것을 뜻한다)
예를들어 main 스레드는 스택 공간이 비어 종료되어도 Thread-0 스레드가 아직 실행하는 중이면 JVM은 종료되지 않는다.
하지만 데몬은 종료되지 않아도 JVM은 종료되고, 사용자 스레드가 종료되지 않으면 JVM도 종료되지 않는다.
public class DaemonThreadMain {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName() + ": main() start");
DaemonThread daemonThread = new DaemonThread();
daemonThread.setDaemon(true); // 데몬 스레드 여부 (기본값이 false라 사용자 스레드로 됨)
daemonThread.start();
System.out.println(Thread.currentThread().getName() + ": main() end");
}
static class DaemonThread extends Thread {
public void run() {
System.out.println(Thread.currentThread().getName() + ": run()");
try {
Thread.sleep(10000); // 10초간 실행
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(Thread.currentThread().getName() + ": run() end");
}
}
}
데몬 스레드가 아니라 사용자 스레드로 가정했을 때, Thread-0에서 run()을 출력하고 10초간 대기했다가 run() end가 찍혀야 맞는데 아래 출력 내용처럼 실행하자마자 바로 종료되어 버린다. 이게 바로 데몬 스레드다. main 스레드가 Thread-0 스레드에 일을 시키고 main 스레드는 끝났는데 일을 시킨 스레드가 데몬이기에... 바로 종료-! (사용자 스레드는 끝났다고 판단)
main: main() start
main: main() end
Thread-0: run()
만약 setDaemon(false); 으로 바꾸면 10초간 대기하고 run() end 를 찍고 종료하게 된다.