在讲守护线程之前,需要先了解一个相对应的概念——用户线程。用户线程可以理解为系统的工作线程,用于处理业务上的操作。而守护线程,顾名思义,它负责守护系统,默默地在后台进行一些系统层面的处理。比如负责垃圾回收、JIT等的线程就可以称为守护线程。当用户线程全部结束,也就代表着系统没有任务需要处理了,系统可以退出了,当系统退出后守护线程的守护对象也就不存在了,守护线程没有继续运行的必要了。在一个Java应用内,如果系统中只剩守护线程在运行,虚拟机就会退出。
下面简单看一下守护线程的使用:
public class DaemonDemo {
public static class DaemonT extends Thread {
public void run() {
while(true) {
System.out.println("I'm alive.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main (String[] args) throws InterruptedException(){
DaemonT t = new DaemonT();
t.setDaemon(true);
t.start();
Thread.sleep(2000);
}
}
上述代码中,将t设置为守护线程。需要注意的是,设置守护线程要在调用start()之前,否则会抛出异常。以下是JDK中设置守护线程相关的代码:
public final void setDaemon(boolean on) {
checkAccess();
// 如果线程已经开始运行,将抛出异常
if (isAlive()) {
throw new IllegalThreadStateException();
}
daemon = on;
}
线程在抛出这个异常后依然会继续运行,不过是作为用户线程。因此如果忽略了这个异常,可能会导致程序不能正常退出。
在之前的例子中,由于t被设为守护线程,系统中只有主线程main作为用户线程,因此在main线程休眠2秒并退出后,整个程序也随之结束。但如果没有把t设置为守护线程,main结束后t依然会继续运行,程序也就无法结束。