基本概念
在 Java 中通常有两种线程:守护线程(Daemon Thread )和用户线程(User Thread )
- 守护线程:是一种特殊的线程,在后台默默地完成一些系统性的服务,比如垃圾回收线程、
JIT 线程都是守护线程 - 用户线程:可以理解为是系统的工作线程,它会完成这个程序需要完成的业务操作。如我们使用
Thread 创建的线程在默认情况下都属于用户线程
怎样使线程成为用户线程与守护线程
- 通过
Thread.setDaemon(false) 设置为用户线程 - 通过
Thread.setDaemon(true) 设置为守护线程 - 如果不设置线程属性,那么默认为用户线程
线程属性的设置要在线程启动之前,否则会报 IllegalThreadStateException 异常
守护线程与用户线程的区别
用户线程
public class UserThread {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
while (true) {
try {
Thread.sleep(1000);
System.out.println("我是用户线程......");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
Thread.sleep(3000);
System.out.println("主线程执行完毕......");
}
}
运行上面代码,结果如下
可以看到主线程已经结束了,但是程序无法退出;原因:用户线程的内部有个死循环,一直处于运行状态,无法结束
守护线程
public class UserThread {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
while (true) {
try {
Thread.sleep(1000);
System.out.println("我是用户线程......");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.setDaemon(true);
thread.start();
Thread.sleep(3000);
System.out.println("主线程执行完毕......");
}
}
运行上面代码,结果如下
程序可以正常结束了,代码中通过 thread.setDaemon(true) 将 thread 线程设置为守护线程,main 方法所在的主线程执行完毕之后,程序就退出了
区别
- 主线程结束后,用户线程还是会继续运行的,此时
JVM 是存活的 - 如果没有用户线程,都是守护线程,那么
JVM 结束,则所有的线程都会结束 - 如果用户线程全部结束了,意味着程序需要完成的业务操作已经结束了,系统可以退出了。所以当系统只剩下守护进程的时候,
JVM 会自动退出的
守护线程适用场景
针对于守护线程的特点,Java 守护线程通常可用于开发一些为其它用户线程服务的功能。比如说心跳检测,事件监听等。Java 中最有名的守护进程当属 GC 垃圾回收
总结
Java 中的线程分为用户线程和守护线程- 程序中的所有的用户线程结束之后,不管守护线程处于什么状态,
JVM 都会自动退出 - 调用线程的实例方法
setDaemon() 来设置线程是否是守护线程 setDaemon() 方法必须在线程的 start() 方法之前调用,在后面调用会报异常,并且不起效
|