为什么SpringBoot中main方法执行完毕后程序不会直接退出呢

# 为什么SpringBoot中main方法执行完毕后程序不会直接退出呢

# 1. 简介

正常情况下我们main方法执行结束后,该进程就结束了。那为什么springboot main函数执行完不会退出呢?

image-20220515222654390
image-20220515222654390

针对这个问题我们可以转化一下思路:一个JVM进程,在什么情况下会正常退出?

# 2. 什么情况JVM进程,在什么情况下会正常退出?

# 2.1 方式1:System.exit()Runtime.exit()

使用System.exit()Runtime.exit()可以直接导致当前JVM进程退出,

但是仔细想想这个好像跟SpringBoot没啥关系哈

# 2.2 方式2:非daemon进程完全终止

另外一个可能会导致进程退出的是所有的非daemon进程完全终止,那么根据这个条件反推的话是不是说只要保证SpringBoot进程中包含1个以上的daemon进程就可以保证程序不会退出

# 3. SpringBoot是如何实现

我们以SpringBoot默认使用的Tomcat容器为例,在我之前SpringBoot源码分析的文章中也提到过,在启动Tomcat的时候,会调用TomcatWebServerinitialize方法,在这个方法中会调用一个startDaemonAwaitThread方法

private void startDaemonAwaitThread() {
        Thread awaitThread = new Thread("container-" + containerCounter.get()) {
            public void run() {
                TomcatWebServer.this.tomcat.getServer().await();
            }
        };
        awaitThread.setContextClassLoader(this.getClass().getClassLoader());
        awaitThread.setDaemon(false);
        awaitThread.start();
    }

下面我们在深挖一下,在Tomcat的this.tomcat.getServer().await()这个方法中,线程是如何实现不退出的。这里为了阅读方便,去掉了不相关的代码。

public void await() {
        // ...
        if( port==-1 ) {
            try {
                awaitThread = Thread.currentThread();
                while(!stopAwait) {
                    try {
                        Thread.sleep( 10000 );
                    } catch( InterruptedException ex ) {
                        // continue and check the flag
                    }
                }
            } finally {
                awaitThread = null;
            }
            return;
        }
        // ...
    }

在await方法中,实际上当前线程在一个while循环中每10秒检查一次 stopAwait这个变量,它是一个volatile类型变量,用于确保被另一个线程修改后,当前线程能够立即看到这个变化。如果没有变化,就会一直处于while循环中。这就是该线程不退出的原因,也就是整个spring-boot应用不退出的原因。

# 参考文章

科普:为什么SpringBoot中main方法执行完毕后程序不会直接退出呢 open in new window

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值