守护线程
定义
在Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程)
用户线程: 是指用户自定义创建的线程,主线程停止,用户线程不会停止
守护线程:为所有非守护线程提供服务的线程;换句话说,任何一个守护线程都是整个JVM中所有非守护线程的保姆;只要当前JVM实例中尚存在任何一个非守护线程没有结束,守护线程就全部工作只有当最后一个非守护线程结束时,守护线程随着JVM一 同结束工作。
如何使用
Thread t = new MyThread();
t.setDaemon(true);//设置当前线程为守护线程
t.start();
注意:
- thread.setDaemon(true)必须在thread.start()之前设置,否则会报出一个IllegalThreadStateException异常。你不能把正在运行的常规线程设置为守护线程。
- 在守护线程中,编写代码要注意:守护线程不能持有任何需要关闭的资源,例如打开文件等,因为虚拟机退出时,守护线程没有任何机会来关闭文件,这会导致数据丢失。
特性
- 当 JVM 中不存在任何一个正在运行的非守护线程时,则 JVM 进程即会退出。也就是说当JVM中只有守护线程存在时JVM 会自动退出,守护线程终止。
- 在Daemon线程中产生的新线程也是Daemon的。
- 守护线程是对与整个JVM来说的,只要JVM中存在非守护线程,所有的守护线程就全部工作,只有当JVM中所有的非守护线程全部结束,此时守护线程才会终止(并不是调用它的父线程终止它就会终止)
特性分析
- 特性2:在Daemon线程中产生的新线程也是Daemon的。
public class DaemonThread2 {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
Thread innerThread = new Thread(() -> {
try {
while (true) {
System.out.println("守护线程,执行心跳检测");
Thread.sleep(1_000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
innerThread.start();
try {
Thread.sleep(1_000);
System.out.println("用户线程 结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t.setDaemon(true);
t.start();
}
}
运行结果为空
分析:线程t为守护线程,所以它的子线程innerThread 也是守护线程,当主线程终止时,jvm退出守护线程终止,所以没有数据打印出来
- 特性3:守护线程是对与整个JVM来说的,只要JVM中存在非守护线程,所有的守护线程就全部工作,只有当JVM中所有的非守护线程全部结束,此时守护线程才会终止(并不是调用它的父线程终止它就会终止)
public class DaemonThread2 {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
Thread innerThread = new Thread(() -> {
try {
while (true) {
System.out.println("t0 守护线程,执行心跳检测");
Thread.sleep(1_000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
innerThread.setDaemon(true);
innerThread.start();
try {
Thread.sleep(1_000);
System.out.println("t0 用户线程 结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t1 = new Thread(() -> {
Thread innerThread = new Thread(() -> {
try {
while (true) {
System.out.println("t1 守护线程,执行心跳检测");
Thread.sleep(1_000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
innerThread.setDaemon(true);
innerThread.start();
try {
Thread.sleep(3_000);
System.out.println("t1 用户线程 结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
t.start();
}
}
运行结果:
分析:t0 t1 两个线程中都有一个守护线程执行心跳检测,当t0结束时t0的守护线程依然存在,直到t1也结束,整个程序中中不存在任何一个正在运行的非守护线程时,t0的守护线程才结束