一、什么是Daemon线程
Daemon线程也是守护线程,它是一种支持型的线程,主要用在程序的后台调度以及一些支持性(服务性)的工作,常见的例子:JVM中垃圾回收线程就是典型的守护线程
二、守护线程和用户线程的区别
守护线程与用户线程的区别发生在JVM的离开:
- 可以说JVM想要运行,用户线程也必须运行
- 守护线程是服务于用户线程的,如果用户线程不在了,那么守护线程的存在是没有意义的,此时该程序(进程)就没有运行的必要了,JVM也就退出了
- 守护线程的优先级是低于用户线程的
三、用户设置守护线程
守护线程并不是固定死的,用户也可以将自己的线程(服务性质)设置为守护线程,设置方法为Thread.setDaemon()方法,我们看看源码:
public final void setDaemon(boolean on) {
checkAccess();
if (isAlive()) {
throw new IllegalThreadStateException();
}
// daemon属性默认为false
daemon = on;
}
我们可以通过setDaemon(true)来设置当前线程为守护线程,但是需要注意的是,该方法必须在线程启动前的执行,即执行在线程NEW状态之后,RUNNABLE之前的,因为源码中的**isAlive()**会检测当前线程是否是活跃状态,即启动或正常执行状态,如果isAlive()为true,则抛出异常
Thread daemonTread = new Thread();
daemonThread.setDaemon(true);
// 返回 true 则为守护线程
daemonThread.isDaemon();
- 在Daemon中产生的新线程也是守护线程
- 前面说到了,服务性质的线程可以设置为守护线程,类似于读写操作、计算逻辑。
- 如果带有这些操作的线程被设置为守护线程,在它执行时,有用户线程在执行的话还好说,但是可能会出现该线程创建完成且启动但是还没有执行到读写操作,尤其是写操作,可能是作为某个程序的最后一步执行,那么此时该程序中的用户线程都已经执行完毕了,而main函数只负责创建守护线程并启动,然后,main线程也会关闭,JVM发现没有用户线程了,便会退出,守护线程也会终止,此时可能还来不及进行写操作。