我正在参加「掘金·启航计划」
1. 背景
Thread 有一个方法:setDaemon(),是用来设置 daemon 变量的。如果 daemon 为true,则代表线程是一个后台线程,如果 damon 为 false,则代表线程是一个非后台线程。平时我们创建的线程,默认都是非后台线程。
后台线程有很多叫法,有叫 daemon 线程的,也有叫守护线程的。
JVM 进程例退出的前提是所有非后台线程都执行完成。这也就是为什么有时候 main() 方法都执行完成了,JVM 进程还没退出的原因。接下来我们看两个案例来体会下。
关键字:后台线程;守护线程;Thread
2. 案例一:daemon 为 false
我们先看看 daemon 为 false 的例子,如下。
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
try {
Thread.sleep(60000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "THREAD_01");
t.setDaemon(false); // daemon 变量默认就是 false,不需要显示设置,这里为了更好理解写在这里
t.start();
System.out.println("main 函数执行完成");
}
控制台已经打印了日志:main 函数执行完成,但 JVM 进程没有退出。这是因为我们把 daemon 变量设置为 false ,起了一个非后台线程。
因为还有执行中的非后台线程,所以 JVM 进程不会退出。
运行过程中,再看看线程栈,THREAD_01(构造线程进程时设置的名字)还处于 TIMED_WAITING 状态,没有执行完。
案例二:daemon 为 true
再看看 daemon 为 true 的例子,如下,这块代码和案例一的唯一区别就是把 daemon 设置为 true。
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
try {
Thread.sleep(60000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "THREAD_01");
t.setDaemon(true);
t.start();
System.out.println("main 函数执行完成");
}
daemon 为 true,说明起的线程是一个后台线程。控制台打印完日志:main 函数执行完成,JVM 就退出了,一点没等 60s 才能执行完的 THREAD_01 线程。
3. 后台线程的使用场景
那么后台线程都有哪些使用场景呢?常见的使用场景如下:
- JVM 内置的 GC 线程,Finalizer 线程都是后台线程
- 日常工作中,如果需要打点、内存泄露检测、监控等,也可以使用后台线程。
4. 总结
Thread 的 setDaemon() 方法用来设置线程是否是后台线程,默认创建的线程都是非后台线程。后台线程常常使用在:监控、检测、打点等场景。
© 版权声明
文章版权归作者所有,未经允许请勿转载,侵权请联系 admin@trc20.tw 删除。
THE END