守护线程是依附于用户线程的后台线程,JVM退出时不等待其完成、不触发finally/shutdown hooks/异常处理器,仅适用于可丢弃的辅助任务。

守护线程是为其他线程服务的后台线程,它本身不承担关键业务逻辑,也不影响程序主流程的存续。
生命周期完全依附于非守护线程
只要所有非守护线程(即用户线程)执行完毕或终止,JVM 就会立即准备退出,此时守护线程无论处于什么状态、是否正在运行循环或等待 I/O,都会被直接终止。
- 不会等待守护线程执行完当前任务,哪怕它正写日志、发心跳、清理缓存
- 无法通过 interrupt() 主动通知停止,因为 JVM 是“强制下线”,不是协作式中断
- 线程状态可能停留在 RUNNABLE、TIMED_WAITING 或 BLOCKED,但执行流被硬性切断
启动前必须显式设置,且不可逆
setDaemon(true) 只能在 Thread 处于 NEW 状态时调用,一旦 start() 执行,再设就会抛出 IllegalThreadStateException。
- 子线程默认继承父线程的 daemon 属性,所以主线程创建的线程默认是非守护的
- 不能在 run() 方法里动态切换守护状态,也没有 getDaemon() 的反向查询必要——它的角色从创建起就已固定
JVM 退出时它不参与资源收尾
守护线程中打开的文件、数据库连接、网络通道等资源,不会获得任何释放机会。
- finally 块不会执行
- shutdown hooks 不会被触发
- Thread.UncaughtExceptionHandler 也不会生效
- 所以绝不能在守护线程里做需要可靠关闭的操作,比如 commit 事务、flush 文件、close socket
典型用途和设计边界
它适合做那些“可丢弃、无副作用、纯辅助”的工作。
- 监控指标采集、JVM 内部 GC、日志异步刷盘(有丢失容忍)、定时健康检查
- 不适合:消息确认、回调通知、上传进度同步、资源池优雅关闭
- 判断标准很简单:如果这个任务中途被砍掉,系统是否仍能保持一致性和可用性?不能,那就别放守护线程里

















