什么是守护线程?
1. 核心定义
守护线程(Daemon Thread)是Java中一种后台服务线程,具有以下特点:
- 当所有用户线程结束时,守护线程自动终止
- 不能单独存在,必须依附于用户线程(例如主线程)
- 典型应用:垃圾回收、内存管理、日志记录等后台任务
2. 核心特性(对比用户线程)
Thread daemonThread = new Thread(() -> {
while(true) {
System.out.println("后台服务中...");
try { Thread.sleep(1000); }
catch (InterruptedException e) {}
}
});
daemonThread.setDaemon(true); // ← 设置为守护线程
daemonThread.start();
特性 | 用户线程 | 守护线程 |
---|---|---|
JVM是否等待其完成 | 必须等待 | 不等待 |
终止时机 | 任务完成 | 随用户线程结束强制终止 |
优先级 | 默认继承父线程优先级 | 默认继承父线程优先级 |
异常处理 | 可捕获处理 | 异常直接终止线程 |
3. 实际应用场景
场景案例:在线文档编辑器中的自动保存功能
// 自动保存守护线程
Thread autoSave = new Thread(() -> {
while(true) {
autoSaveDocument();
try { Thread.sleep(300_000); } // 每5分钟保存
}
});
autoSave.setDaemon(true);
autoSave.start();
4. 注意事项(血泪教训)
- 资源释放问题:守护线程不要持有需要关闭的资源(如数据库连接)
- 不可靠执行:
finally
代码块可能不会执行 - 继承特性:守护线程创建的新线程自动成为守护线程
- 启动顺序:必须在启动前设置
setDaemon(true)
5. 底层原理
JVM通过线程状态检查机制实现守护逻辑:
6. 面试进阶问题
- 守护线程中的
finally
代码块一定会执行吗? - 如何在守护线程中实现可靠资源回收?
- 守护线程池与普通线程池有什么区别?
总结
守护线程就像公司的后勤部门,当所有"业务部门"(用户线程)下班后,后勤会自动停止工作。使用时要注意它的"临时工"特性,适合处理非关键性后台任务,但不能依赖它完成重要工作。