
Java有两种状态的线程:守护线程和非守护线程(用户线程),下面谈谈两者的区别。
1.守护线程
守护线程用来服务于用户线程,不需要上层逻辑介入,当然我们也可以手动创建一个守护线程,我们只需要调用用户线程里面的setDaemon方法并且设置成true,就表示这个线程是守护线程。
例如垃圾回收线程:gc线程,就是一个很称职的守护者,并且这种线程并不属于程序中不可或缺的部分。
因此,当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程,反过来说,只要任何非守护线程还在运行,程序就不会终止。
2.非守护线程
用户线程:用户线程即我们手动创建的线程,默认情况下我们创建的线程或线程池都是用户线程,所以用户线程也被称之为非守护线程。
3.守护线程和非守护线程的区别
比较明显的区别之一是用户线程结束,JVM 退出,不管这个时候有没有守护线程运行,而守护线程不会影响 JVM 的退出。
示例如下:
public class Daemon {
//启动该类,将会构造两条线程,main线程和一条子线程。
public static void main(String[] args) throws InterruptedException {
//测试非守护线程
//可以看到,输出"main线程结束"之后,子线程还在继续输出,程序没有结束
// test1();
//测试守护线程
//可以看到,输出"main线程结束"之后,子线程没有继续输出,程序结束
test2();
}
/**
* 测试非守护线程
*
* @throws InterruptedException
*/
public static void test1() throws InterruptedException {
Thread thread = new Thread(() -> {
while (true) {
try {
Thread.currentThread().sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程非守护线程");
}
});
thread.start();
Thread.currentThread().sleep(1000);
System.out.println("main线程结束");
}
//测试守护线程
public static void test2() throws InterruptedException {
Thread thread = new Thread(() -> {
while (true) {
try {
Thread.currentThread().sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程守护线程");
}
});
thread.setDaemon(true);
thread.start();
Thread.currentThread().sleep(1000);
System.out.println("main线程结束");
}
}
使用jps查看java进程,可以发现如果子线程是守护线程那么主线程结束,子线程也结束了。
如果子线程不是守护线程那么主线程结束,子线程没有结束。
简而言之,普通线程在没执行完的时候不能退出,而守护线程是把普通线程守护起来运行,线程退出了守护也一起退出。
关于mikechen
mikechen睿哥,10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。