我是靠谱客的博主 平淡诺言,最近开发中收集的这篇文章主要介绍java执行完main就结束了吗_科普:为什么SpringBoot中main方法执行完毕后程序不会直接退出呢...,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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

大部分人应该都知道使用System.exit()或Runtime.exit()可以直接导致当前JVM进程退出,但是仔细想想这个好像跟SpringBoot没啥关系哈

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

接下来我们去看下SpringBoot是如何基于这个特性实现的

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

privatevoidstartDaemonAwaitThread() {

Thread awaitThread = new Thread("container-" + containerCounter.get()) {

publicvoidrun() {

TomcatWebServer.this.tomcat.getServer().await();

}

};

awaitThread.setContextClassLoader(this.getClass().getClassLoader());

awaitThread.setDaemon(false);

awaitThread.start();

}

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

publicvoidawait() {

// ...

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应用不退出的原因。

往期好文

好文章就该:收藏、转发、在看!!!

最后

以上就是平淡诺言为你收集整理的java执行完main就结束了吗_科普:为什么SpringBoot中main方法执行完毕后程序不会直接退出呢...的全部内容,希望文章能够帮你解决java执行完main就结束了吗_科普:为什么SpringBoot中main方法执行完毕后程序不会直接退出呢...所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部