前言:当springboot被kill的时候,即使线程还在执行,也会结束。虽然k8s和springboot都有优雅关闭,但是还是会影响当前jvm应用。为了避免有些线程没有执行完就关闭的情况,使用DisposableBean在Bean生命周期结束前调用destory()方法做一些收尾工作。
package com.example.springshutdown; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.DisposableBean; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.util.*; import java.util.concurrent.TimeUnit; /** * springBean销毁之前执行检查 */ @Component public class MyDisposableBean implements DisposableBean { private static final Logger logger = LoggerFactory.getLogger(MyDisposableBean.class); private static final Set<Thread> threadList = new HashSet<>(); public static void addDaemonThread() { threadList.add(Thread.currentThread()); } @PostConstruct public void construct() { new Thread(() -> { while (true) { Iterator<Thread> iterator = threadList.iterator(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { throw new RuntimeException(e); } while (iterator.hasNext()) { if (!iterator.next().isAlive()) { iterator.remove(); } } } }).start(); } @Override public void destroy() throws Exception { logger.info("系统准备关闭,检查自定义守护线程是否还在运行"); while (true) { int i = 0; for (Thread t : threadList) { Thread.sleep(1000); logger.info("线程" + t.getId() + " " + t.getName() + " " + t.isAlive()); if (t.isAlive()) { i++; } } if (i == 0) { break; } } logger.info("关闭服务"); } }