守护线程的定义
守护线程,也可称为服务线程,当程序中没有可服务的线程时会自动离开,因此,守护线程的优先级比较低,用于为其他的线程等提供服务。
守护线程,它是一种专门为用户线程提供服务的线程,它的生命周期依赖于用户线程。
只有JVM中仍然还存在用户线程正在运行的情况下,守护线程才会有存在的意义。
守护线程的作用与应用场景
JVM 中的垃圾回收线程就是典型的守护线程,如果说不具备该特性,会发生什么呢?
当 JVM 要退出时,由于垃圾回收线程还在运行着,导致程序无法退出,这就很尴尬了!!!由此可见,守护线程的重要性了。
通常来说,守护线程经常被用来执行一些后台任务,但是呢,你又希望在程序退出时,或者说 JVM 退出时,线程能够自动关闭,此时,守护线程是你的首选。
守护线程的特点
1.在所有的用户线程都执行完毕后,守护线程会自动关闭;
2.一个线程如果要定义成守护线程,它必须可以随时关闭,尤其是那些重要的线程不能定义成守护线程,比如mysql输入之类的,不能中断;
3.线程池中没有守护线程,它会自动把守护线程转成用户线程;
4.将线程变为守护线程,通过设置线程的方法 setDaemon(true)即可,但该方法必须在start()方法之前执行才可以,启动后的线程,不能中途改变线程类型
5.守护线程具有传递性,当线程设置成守护线程了,那么它的子线程也是守护线程。
最经典的守护线程:GC垃圾回收线程。
为什么需要守护线程
首先要明白,当存在任意一个用户线程
的时候,JVM就不会退出。
那么如果只有用户线程的话,然后有一种需求需要一种无限循环的线程,例如,一个定时触发任务的线程:
class MikeChenJiaGou extends Thread {
@Override
public void run() {
while (true) {
System.out.println("mikechen.cc互联网架构网站要运行到天荒地老");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
break;
}
}
}
}
如果这个用户线程不结束,JVM进程就无法结束,这就导致一个问题:由谁负责结束这个线程?
所以Java就提供了守护线程(Daemon Thread)来帮助我们解决这一个问题。
如何识别守护线程?
想要查看线程到底是用户线程还是守护线程,可以通过 Thread.isDaemon() 方法来判断,如果返回的结果是 true 则为守护线程,反之则为用户线程。
@Test public void whenCallIsDaemon_thenCorrect() { NewThread daemonThread = new NewThread(); NewThread userThread = new NewThread(); daemonThread.setDaemon(true); daemonThread.start(); userThread.start(); assertTrue(daemonThread.isDaemon()); assertFalse(userThread.isDaemon()); }
Java守护线程怎么使用
使用很简单,只是在调用start()方法前,调用setDaemon(true)把该线程标记为守护线程
Thread mikechenThread = new MikeChenThread();
mikechenThread .setDaemon(true);
mikechenThread .start();
注意
:mikechenThread
.setDaemon(true)必须在mikechenThread
.start()之前设置,否则会抛出IllegalThreadStateException异常。
陈睿mikechen
10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获取更多技术干货!
后台回复【面试】即可获取《史上最全阿里Java面试题总结》,后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》