Spring MVC SpringBoot Web项目中没有主线程

inn6fuwd  于 2022-11-14  发布在  Spring
关注(0)|答案(3)|浏览(166)

在我启动一个SpringBoot web项目之后。我找不到使用jcmd $pid Thread.print的主线程。我也找不到使用hsdb的主线程。main线程去了哪里?

fjaof16o

fjaof16o1#

我不知道您使用了什么工具来创建您的Sping Boot 项目,但如果您通过Spring Initializrhttps://start.spring.io/)创建了它,它应该位于路径YOUR_PROJECT_NAME/src/main/java/YOUR_PERSONALIZED_PATH/上。
创建/执行main thread的文件的名称应该在该路径内,并且应该称为YOUR_PROJECT_NAME+Application.java

r3i60tvu

r3i60tvu2#

对于大多数Sping Boot 应用,SpringApplication::run涉及启动一个web服务器(Tomcat、Undertow、Jetty、Netty)。这些服务器创建它们自己的非守护进程线程。然后返回对SpringApplication::run的调用,主线程退出。然后VM通过其他非守护进程线程保持活动-确切的名称取决于所使用的web服务器。

@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}
beq87vna

beq87vna3#

web应用将main方法委托给SpringApplication.runSpringApplication.run将执行Spring初始化等流程,Spring初始化完成后,main方法的生命周期结束。
为什么java进程没有main方法就不退出?
java.c

/* Build platform specific argument array */
mainArgs = CreateApplicationArgs(env, argv, argc);
CHECK_EXCEPTION_NULL_LEAVE(mainArgs);

/* Invoke main method. */
(*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);

/*
 * The launcher's exit code (in the absence of calls to
 * System.exit) will be non-zero if main threw an exception.
 */
ret = (*env)->ExceptionOccurred(env) == NULL ? 0 : 1;
LEAVE();

#define LEAVE() \
do { \
    if ((*vm)->DetachCurrentThread(vm) != JNI_OK) { \
        JLI_ReportErrorMessage(JVM_ERROR2); \
        ret = 1; \
    } \
    if (JNI_TRUE) { \
        (*vm)->DestroyJavaVM(vm); \
        return ret; \
    } \
} while (JNI_FALSE)

因为它是在宏定义的注解中声明离开的。
总是分离主线程,这样当应用程序的main方法退出时,它看起来已经结束。如果main抛出异常,这将调用未捕获的异常处理程序机制。未捕获的异常处理程序不能更改启动程序的返回代码,除非调用System.exit。等待所有非守护进程线程结束,然后销毁VM。这实际上将创建一个名为“DestroyJavaVM”的普通新Java等待线程。但这将被视为与执行main的线程不同的线程,即使它们是同一个C线程。2这使得mainThread.join()和mainThread.isAlive()能够按预期工作。
在这种情况下,进程具有非守护进程线程,因此进程不会退出。

相关问题