JVM 进程没有退出的罪魁祸首:Java daemon 线程

我正在参加「掘金·启航计划」

1. 背景

Thread 有一个方法:setDaemon(),是用来设置 daemon 变量的。如果 daemon 为true,则代表线程是一个后台线程,如果 damon 为 false,则代表线程是一个非后台线程。平时我们创建的线程,默认都是非后台线程。

后台线程有很多叫法,有叫 daemon 线程的,也有叫守护线程的。

image.png

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 进程不会退出。
image.png

运行过程中,再看看线程栈,THREAD_01(构造线程进程时设置的名字)还处于 TIMED_WAITING 状态,没有执行完。
image.png

案例二: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() 方法用来设置线程是否是后台线程,默认创建的线程都是非后台线程。后台线程常常使用在:监控、检测、打点等场景。

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYTnv0TB' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片