当前位置: 首页 > news >正文

线程池未争取关闭导致的一个bug

前提
自己写了一个任务执行器TaskStarter,在SpringBoot启动时自动执行一些初始化任务。使用数据库来保证一些幂等操作。
为了防止任务执行过久或者执行过程中失去响应,每个任务执行时都需要启动一个异步的任务来更新任务的RUN_TIME。
这个异步任务的执行由一个scheduledExecutor执行。
当任务执行失败时,应该在控制台打印错误并退出spring boot的启动。但现实情况是程序并未退出。

代码

任务执行器实现了ApplicationRunner接口,由SpringBoot在应用启动时调用run()方法执行业务逻辑。
并且构造函数中注册了jvm退出函数,在退出时关闭线程池。

@Component
@Slf4j
public class TaskStarter implements ApplicationRunner {protected ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(1);public TaskStarter() {this.threadPoolExecutor = new ThreadPoolExecutor(5,5,30,TimeUnit.SECONDS,new LinkedBlockingQueue<>(100),new ThreadFactory() {private final AtomicInteger integer = new AtomicInteger(1);@Overridepublic Thread newThread(Runnable r) {return new Thread(r, "taskRunner-" + integer.getAndIncrement());}});this.threadPoolExecutor.allowCoreThreadTimeOut(true);SpringApplication.getShutdownHandlers().add(() -> {//关闭线程池,忽略队列中的任务threadPoolExecutor.shutdownNow();scheduledExecutor.shutdownNow();});}
}

此处之2个细节:
1、通过Executors创建的线程池的线程都是非daemon的
2、导致jvm退出的几种情况:
正常关闭:当最后一个非守护线程结束或者调用了System.exit或者通过其他特定平台的方法关闭(发送SIGINT,SIGTERM信号等)
强制关闭:通过调用Runtime.halt方法或者是在操作系统中直接kill(发送SIGKILL信号)掉JVM进程
异常关闭:运行中遇到RuntimeException异常等。

在Spring Boot启动报错后,由于scheduledExecutor中的线程是非daemon导致jvm未退出。

解决方法
TaskStarter实现SmartLifecycle接口,并在stop()方法中调用线程池的shutdown方法,退出线程池。

http://www.gsyq.cn/news/8629.html

相关文章:

  • 【500 kHz-6 GHz“全频段通吃”神器】 ——成都恒利泰
  • 成都恒利泰——【5 MHz-1 GHz“信号分身术”神器】
  • 详细介绍:【智慧城市】2025年中国地质大学(武汉)暑期实训优秀作品(2):智慧城市西安与一带一路
  • OpenCV-图像通道提取与处理
  • Mac环境安装Nginx指南实录
  • N皇后问题(DFS)
  • android studio发现设备立刻就掉
  • 见证语音领域 GPT-3 时刻!小米开源端到端语音模型 MiMo Audio;Xbox上线游戏助手,实时游戏理解+语音交互丨日报
  • go语言学习之基本数据类型转字符串
  • DeepLearning-LoRA 及其先进变体技术指南
  • 详细介绍:【最新版】SolidWorks2025安装包下载与安装图文教程
  • 华为eNSP防火墙综合网络结构训练.docx - 教程
  • 第二节中央处理单元CPU知识点
  • makefile 入门2(变量赋值)
  • JS复制并气泡提示
  • 实用指南:【鸿蒙面试题-6】LazyForEach 懒加载
  • 第二周预习报告(AI)
  • .netcore的Lucene.Net基础应用
  • 在Ubuntu 16.04上安装openjdk-6/7/8-jdk的步骤
  • 物流行业信息咨询智能问答系统
  • 线性代数 行列式 | 子式 / 主子式 / 顺序主子式 / 余子式 / 代数余子式 - 教程
  • HBase 的自带命令行工具 hbase shell 的基本使用
  • 重塑公司绩效管理的 6 种方法
  • Confluent-Kafka-go 发布超过 1M 消息失败困难克服
  • 组件重新装载时 useSWR 会发起请求
  • Seedream 4.0 简直绝了!
  • mysql查询死锁,mysql查询死锁方法
  • 【IEEE出版、已连续5届稳定快速EI检索】第六届计算机工程与智能控制学术会议(ICCEIC 2025)
  • 向上一步——当做事纠结的人停止决策内耗,你就是掌控自己的神!
  • Windows平台安装cocos2d-x V3.17.2