SpringBoot是如何保证服务启动后不自动停止的

发布时间 2023-11-09 18:23:36作者: 残城碎梦

一般项目执行后,当程序结束会自动关闭程序。但Springboot项目,启动后,只要不发生error错误,一般不会自动停止。

这是为什么呢?

简单Java阻止停止

为了保证一个服务能够持续有效地对外提供服务,一般会有相应的处理方式,比如:

  • 服务器上的守护进程脚本

但是,在Java代码层面,除了shell脚本之外,还有一种很特别的方式,保证服务不会执行后停止。

  • 死循环!文雅点叫自旋锁。

比如下面的例子:

public class ThreadDemo2 {
    public static volatile boolean isDead = false;
    public static void main(String[] args) throws InterruptedException {
        while (!isDead){
            Thread.sleep(4000);
        }
    }
}

程序执行后,会进入自旋锁的代码逻辑中,每隔4s,检查一下isDead值。

如果isDead一直为false,那么程序将不会自动停止。

但是,设置在主线程中,此处自旋锁触发后,导致后续代码并不会继续执行,影响到后面的逻辑处理,显然是不可取的。

如果,单独开辟一个新的线程,去处理这个活,主线程依旧去执行别的逻辑呢?

public class TestThread {
    public static volatile boolean isDead = false;

    public static void main(String[] args) throws InterruptedException {
        //        Thread thread = new Thread(new Runnable() {
        //            @Override
        //            public void run() {
        //                System.out.println("---------");
        //                try {
        //                    while (!isDead){
        //                        Thread.sleep(10000L);
        //                    }
        //                } catch (InterruptedException e) {
        //                    e.printStackTrace();
        //                }
        //            }
        //        });

        Thread thread = new Thread("container-1") {

            @Override
            public void run() {
                System.out.println("---------");
                try {
                    while (!isDead) {
                        Thread.sleep(4000L);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        };
        thread.setDaemon(false);

        thread.start();

        // 主线程暂停40s
        Thread.sleep(40000L);
        // 变更状态
        isDead = true;
    }
}

单独设定一个非守护进程的线程,去干这个活,主线程依旧可以继续执行其他的事。

基于这个思想,接下来看看源码中Springboot底层是如何实现的。

Springboot 底层实现

以Springboot默认整合Tomcat为例。

查看SpringApplication.run

Springboot的项目执行,依据的是run方法,其中的实现方式如下: