文章目录
- 1.概念
- 2.生命周期与行为
- 2. 应用场景
- 3. 示例代码
- 4. 注意事项
1.概念
Daemon : 滴门
在Java中,线程分为两类:用户线程
(User Thread)和守护线程
(Daemon Thread)。
守护线程是后台线程,主要服务于用户线程,当所有的用户线程结束时,守护线程也会自动结束,JVM会随之退出。
守护线程的一个典型例子是垃圾回收线程。守护线程由JVM自己管理,不需要程序员手动结束。
总结:jvm等用户线程全部执行完,然后拉着守护线程一起死。
2.生命周期与行为
启动与运行:守护线程的启动和普通线程一样,通过调用start()方法进入就绪状态,等待CPU调度执行。
终止条件:守护线程会在以下任一条件满足时终止:
- 所有非守护线程结束执行。
- 显式调用Thread.interrupt()或Thread.stop()(已废弃)方法中断线程。
- 程序中主动调用System.exit()结束JVM。
JVM退出:当最后一个非守护线程终止时,即使守护线程仍在执行某任务,JVM也会立即终止,不会等待守护线程完成其任务。
2. 应用场景
没有特殊应用场景,守护线程可以做的事情用户线程也可以做,只是比用户线程少了一步线程间的通信。
守护线程的适用铁律:
当且仅当任务可接受被随时终止,且其终止不会导致数据损坏或逻辑错误时,使用守护线程。
在java web中没必要使用:
因为在java web 中,比如用springboot 创建的web项目,springboot和其内嵌web服务器(比如tomcat)默认使用都是用户线程,他们的生命周期与jvm是强绑定的,也就是说springboot项目中 若中止所有用户线程,其整个jvm进程就会中止,守护线程又是由jvm管理的,所以springboot项目使用守护线程是没有必要使用,用线程池更好创建用户线程能更方便管理。
3. 示例代码
创建守护线程
public class DaemonTest {public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {while (true){}},"t1");//如果没有设置守护线程,主线程结束,t1线程不会结束t1.setDaemon(true);t1.start();TimeUnit.SECONDS.sleep(3);log.debug("main 结束");}
}
4. 注意事项
守护线程不能用作访问持久化资源或者写入文件,因为其会被jvm强行中止导致数据不一致。
守护线程的适用铁律:
当且仅当任务可接受被随时终止,且其终止不会导致数据损坏或逻辑错误时,使用守护线程。