必须在start()前调用setdaemon(true),否则抛illegalthreadstateexception;守护线程不阻止jvm退出,子线程默认继承父线程daemon状态。

Java 中通过 setDaemon(true) 可以将线程设置为守护线程(Daemon Thread),使其在后台运行。但要注意:这个方法必须在线程启动(start())之前调用,否则会抛出 IllegalThreadStateException。
必须在 start() 之前设置
守护线程的属性是线程的初始状态之一,一旦线程开始运行,就无法再修改。例如:
Thread t = new Thread(() -> {
while (true) {
System.out.println("守护线程运行中...");
try { Thread.sleep(1000); } catch (InterruptedException e) { break; }
}
});
t.setDaemon(true); // ✅ 正确:设置在 start 前
t.start();
如果写成:
t.start(); t.setDaemon(true); // ❌ 抛出 IllegalThreadStateException
守护线程的特点:JVM 退出时不等待它
守护线程不会阻止 JVM 退出。当所有用户线程(非守护线程)结束时,JVM 会自动终止,即使守护线程仍在运行。常见用途包括:
- 垃圾回收、监控、日志刷盘等后台支持任务
- 不承担核心业务逻辑,仅辅助主线程运行
- 无需显式关闭,随 JVM 自动结束
主线程默认不是守护线程
Java 程序启动时,main 线程默认是用户线程(isDaemon() 返回 false)。你可以用以下方式验证:
System.out.println(Thread.currentThread().isDaemon()); // 输出 false
子线程默认继承父线程的 daemon 状态。所以如果在 main 线程中创建新线程,它默认也是非守护线程,必须显式调用 setDaemon(true) 才生效。
不能把正在运行的线程转为守护线程
除了必须在 start() 前调用外,还有一点容易忽略:即使线程处于 NEW 状态但尚未启动,只要已经调用了 start()(哪怕还没真正执行到 run 方法),再调用 setDaemon() 就会失败。因此最稳妥的做法是:
- 创建线程后立即设置
setDaemon(true) - 再调用
start() - 避免任何可能的时序依赖
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











