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
10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获取更多技术干货!
后台回复【面试】即可获取《史上最全阿里Java面试题总结》,后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》