阅读 64

springboot通过shutdown进程依然存活的问题

问题描述:

在springboot 正常情况下 使用 shutdown 关闭进程 是正常的,但是如果 jar包 正在运行线程任务时如果调用 shutdown 进行关闭 则会 抛出io异常并且 进程不会正常退出

解决方法:

创建ShutdownAction类

package com.ecolor.energy.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 

Created with IntelliJ IDEA.、

*

Computer: Administrator、

*

Author:QiaXiao19、

*

Date: 2021/9/26 0026 周日 09:14

*

Project:energy

*

Description: No Description

*/ @Slf4j public class ShutdownAction implements ApplicationListener { private ClassWithExecutor classWithExecutor; public ShutdownAction(ClassWithExecutor classWithExecutor) { this.classWithExecutor = classWithExecutor; } @Override public void onApplicationEvent(ContextClosedEvent contextClosedEvent) { classWithExecutor.shutdown(); } public static class ClassWithExecutor { ScheduledExecutorService es; public ClassWithExecutor() { this.es = Executors.newSingleThreadScheduledExecutor(); } public void startScheduledTask() { es.scheduleAtFixedRate(new Runnable() { @Override public void run() { // System.out.println("Printing this every minute"); } }, 0, 3, TimeUnit.SECONDS); } public void shutdown() { // 有序关闭现在的线程 es.shutdown(); try { // 判断当前是否还有没有关闭的线程,超时时间60秒。 boolean b = es.awaitTermination(60, TimeUnit.SECONDS); if (!b){ // 超时时 强制关闭线程池中所有的现成 log.error("this is stop All task"); es.shutdownNow(); } } catch (InterruptedException e) { log.error("this is stop All task"); // e.printStackTrace(); es.shutdownNow(); } } } }

在启动文件处注入以上的类

package com.ecolor.energy;

import com.ecolor.energy.config.ShutdownAction;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;

import javax.annotation.PostConstruct;

@SpringBootApplication
// 开启定时任务
@EnableScheduling
public class EnergyApplication {
    public static void main(String[] args) {
        SpringApplication.run(EnergyApplication.class, args);
    }
    @Bean
    public ShutdownAction.ClassWithExecutor ce() {
        return new ShutdownAction.ClassWithExecutor();
    }

    @Bean
    ShutdownAction sa() {
        return new ShutdownAction(ce());
    }

    @PostConstruct
    public void startScheduledTask() {
        ce().startScheduledTask();
    }
}

结语:

.如果存在定时任务之类的子线程正在执行查询数据库等操作时有可能会出现 先关闭了jdbc的线程然后 子线程会抛出 jdbc线程不存在的异常所以需要在子线程里面考虑这个场景

原文:https://www.cnblogs.com/qianxiaoPro/p/15352321.html

文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐