Java并发-为什么主线程结束了,程序却没有关闭呢?

守护线程与用户线程的定义及区别

Java 中的线程分为两类,分别为 daemon 线程(守护线程)和 user 线程(用户线程)。

在 JVM 启动时会调用 main 函数, main 函数所在的线程就是一个用户线程,其实在 JVM 内部同时还启动了好多守护线程,比如垃圾回收线程。

守护线程定义:当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程。反过来说,只要任何非守护线程还在运行,程序就不会终止

用户线程定义:某种意义上的主要用户线程,只要有用户线程未执行完毕,JVM 虚拟机不会退出

main函数所在线程是一个用户线程,我们自己创建的线程也是一个用户线程。即使主线程结束了,其他用户线程还没有结束,Java程序也不会结束。

 守护线程

Java 中的守护线程和 Linux 中的守护进程是有些区别的,Linux 守护进程是系统级别的,当系统退出时,才会终止。

Java 中的守护线程是 JVM 级别的,当 JVM 中无任何用户进程时,守护进程销毁,JVM 退出,程序终止。总结来说,Java 守护进程的最主要的特点有:

  • 守护线程是运行在程序后台的线程
  • 守护线程创建的线程,依然是守护线程
  • 守护线程不会影响 JVM 的退出,当 JVM 只剩余守护线程时,JVM 进行退出;
  • 守护线程在 JVM 退出时,自动销毁
  • 守护线程应该永远不去访问固有资源,如文件、数据库,因为它会在任何时候甚至在一个操作的中间发生中断。

创建方式:将线程转换为守护线程可以通过调用 Thread 对象的 setDaemon (true) 方法来实现。

守护线程与 JVM 的退出实验

方案一

  • 创建 1 个线程,线程名为 threadOne;
  • run 方法线程 sleep 1000 毫秒后,进行求和计算,求解 1 + 2 + 3 + … + 100 的值;
  • 将线程 threadOne 设置为守护线程;
  • 执行代码,最终打印的结果;

方案二

  • 在方案一基础上加入 join 方法,强制让用户线程等待守护线程 threadOne;
  • 执行代码,最终打印的结果。

方案一结果

方法二结果

 

【分析】方法一产生的结果是因为,主线程(用户线程)执行完毕,JVM直接将守护线程销毁了。

【分析】方法二产生结果,是因为主线程等待守护线程执行完毕后才结束。

public class DaemonTest {
    public static void main(String[] args) throws InterruptedException {
        Thread daemon = new Thread(()->{
            try {
                Thread.sleep(1000);
                int sum = 0;
                for (int i = 0; i < 100; i++) {
                    sum += i;
                }
                System.out.println(sum);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        // 设置守护线程
        daemon.setDaemon(true);
        daemon.start();
//        daemon.join();
        System.out.println("主线程结束");
    }
}

守护线程的作用及使用场景

作用:我们以 GC 垃圾回收线程举例,它就是一个经典的守护线程,当我们的程序中不再有任何运行的 Thread, 程序就不会再产生垃圾,垃圾回收器也就无事可做,所以当垃圾回收线程是 JVM 上仅剩的线程时,垃圾回收线程会自动离开。

应用场景

  • 为其它线程提供服务支持的情况,可选用守护线程;
  • 根据开发需求,程序结束时,这个线程必须正常且立刻关闭,就可以作为守护线程来使用;
  • 如果一个正在执行某个操作的线程必须要执行完毕后再释放,否则就会出现不良的后果的话,那么这个线程就不能是守护线程,而是用户线程;
  • 正常开发过程中,一般心跳监听,垃圾回收,临时数据清理等通用服务会选择守护线程
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

兜兜转转m

一毛钱助力博主实现愿望

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值