【SpringBoot】为异步任务规划线程池
一、线程池的作用
- 防止资源占用无限的扩张
- 调用过程省去资源的创建和销毁所占用的时间
在上一节中,我们的一个异步任务打开了一个线程,完成后销毁。在高并发环境下,不断的分配新资源,可能导致系统资源耗尽。所以为了避免这个问题,我们为异步任务规划一个线程池。
二、定义线程池
在上述操作中,创建一个 线程池配置类TaskConfiguration ,并配置一个 任务线程池对象taskExecutor。
@Configuration
public class TaskConfiguration {@Bean("taskExecutor")public Executor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(10);executor.setMaxPoolSize(20);executor.setQueueCapacity(200);executor.setKeepAliveSeconds(60);executor.setThreadNamePrefix("taskExecutor-");executor.setRejectedExecutionHandler(new CallerRunsPolicy());return executor;}
}
上面我们通过使用 ThreadPoolTaskExecutor 创建了一个 线程池,同时设置了以下这些参数:
| 线程池属性 | 属性的作用 | 设置初始值 |
|---|---|---|
| 核心线程数 | 线程池创建时候初始化的线程数 | 10 |
| 最大线程数 | 线程池最大的线程数,只有在缓冲队列满了之后,才会申请超过核心线程数的线程 | 20 |
| 缓冲队列 | 用来缓冲执行任务的队列 | 200 |
| 允许线程的空闲时间 | 当超过了核心线程之外的线程,在空闲时间到达之后会被销毁 | 60秒 |
| 线程池名的前缀 | 可以用于定位处理任务所在的线程池 | taskExecutor- |
| 线程池对拒绝任务的处理策略 | 这里采用CallerRunsPolicy策略,当线程池没有处理能力的时候,该策略会直接在execute方法的调用线程中运行被拒绝的任务;如果执行程序已关闭,则会丢弃该任务 | CallerRunsPolicy |
- 创建
AsyncExecutorTask类,三个任务的配置和AsyncTask一样,不同的是@Async注解需要指定前面配置的 线程池的名称taskExecutor。
@Component
public class AsyncExecutorTask extends AbstractTask {@Async("taskExecutor")public Future<String> doTaskOneCallback() throws Exception {super.doTaskOne();System.out.println("任务一,当前线程:" + Thread.currentThread().getName());return new AsyncResult<>("任务一完成");}@Async("taskExecutor")public Future<String> doTaskTwoCallback() throws Exception {super.doTaskTwo();System.out.println("任务二,当前线程:" + Thread.currentThread().getName());return new AsyncResult<>("任务二完成");}@Async("taskExecutor")public Future<String> doTaskThreeCallback() throws Exception {super.doTaskThree();System.out.println("任务三,当前线程:" + Thread.currentThread().getName());return new AsyncResult<>("任务三完成");}
}
- 在 单元测试 用例中,注入
AsyncExecutorTask对象,并在测试用例中执行doTaskOne(),doTaskTwo(),doTaskThree()三个方法。
@RunWith(SpringRunner.class)
@SpringBootTest
public class AsyncExecutorTaskTest {@Autowiredprivate AsyncExecutorTask task;@Testpublic void testAsyncExecutorTask() throws Exception {task.doTaskOneCallback();task.doTaskTwoCallback();task.doTaskThreeCallback();sleep(30 * 1000L);}
}
执行一下上述的 单元测试,可以看到如下结果:
开始做任务一
开始做任务三
开始做任务二
完成任务二,耗时:3905毫秒
任务二,当前线程:taskExecutor-2
完成任务一,耗时:6184毫秒
任务一,当前线程:taskExecutor-1
完成任务三,耗时:9737毫秒
任务三,当前线程:taskExecutor-3
执行上面的单元测试,观察到 任务线程池 的 线程池名的前缀 被打印,说明 线程池 成功执行 异步任务!
三、优雅地关闭线程池
由于在应用关闭的时候异步任务还在执行,导致类似 数据库连接池 这样的对象一并被 销毁了,当 异步任务 中对 数据库 进行操作就会出错。
解决方案如下,重新设置线程池配置对象,新增线程池 setWaitForTasksToCompleteOnShutdown() 和 setAwaitTerminationSeconds() 配置:
@Bean("taskExecutor")
public Executor taskExecutor() {ThreadPoolTaskScheduler executor = new ThreadPoolTaskScheduler();executor.setPoolSize(20);executor.setThreadNamePrefix("taskExecutor-");executor.setWaitForTasksToCompleteOnShutdown(true);executor.setAwaitTerminationSeconds(60);return executor;
}
- setWaitForTasksToCompleteOnShutdown(true): 该方法用来设置 线程池关闭 的时候 等待 所有任务都完成后,再继续 销毁 其他的
Bean,这样这些 异步任务 的 销毁 就会先于 数据库连接池对象 的销毁。 - setAwaitTerminationSeconds(60): 该方法用来设置线程池中 任务的等待时间,如果超过这个时间还没有销毁就 强制销毁,以确保应用最后能够被关闭,而不是阻塞住。
相关文章:
【SpringBoot】为异步任务规划线程池
一、线程池的作用 防止资源占用无限的扩张调用过程省去资源的创建和销毁所占用的时间 在上一节中,我们的一个异步任务打开了一个线程,完成后销毁。在高并发环境下,不断的分配新资源,可能导致系统资源耗尽。所以为了避免这个问题…...
SAP ABAP 输出结果带有空格
方法一: 字段内容前增加空格,需使用全角空格,使用半角空格时,ALV显示无效,空格无法显示, 全角与半角的切换方法:shift空格切换, 如下的标记部分,要想通过ALV显示空格&…...
Opengl ES之踩坑记
前因 最近在尝试使用Opengl ES实现一些LUT滤镜效果,在实现这些滤镜效果的时候遇到一些兼容性的坑,踩过这些坑后我希望把这几个坑分享给读者朋友们, 希望同在学习Opengl ES的朋友们能少走弯路。 关于LUT滤镜相关的介绍,也是这个O…...
设计模式第六讲:责任链模式和迭代器模式详解
一. 责任链模式1. 背景在现实生活中,常常会出现这样的事例:一个请求有多个对象可以处理,但每个对象的处理条件或权限不同。例如,公司员工请假,可批假的领导有部门负责人、副总经理、总经理等,但每个领导能批…...
K8s 架构简介(一)
一、前言 在开始学习K8s之前,让我们对容器有一个基本的了解 1.1 什么是容器 一个容器镜像是一个可运行的软件包,其中包含了一个完整的可执行程序,包括代码和运行时需要应用、系统库和全部重要设置的默认值。 通过将应用程序本身ÿ…...
xshell6运行报错:由于找不到mfc110u.dll、MSVCR110.dll无法继续执行代码
今天给大家分享一下我刚装完系统遇到得问题,由于新盟的罗建雨【胡巴】老师帮我给电脑加了固态,又重装了系统,因此电脑里面得所有软件需要重装,在我重装的过程中遇到了一个小问题给大家分享一下,如果大家以后遇到也方便解决。 问题: 安装Xshell时电脑系统报错:“由于找…...
Baklib知识库管理平台,协助组织提升知识管理水平
随着信息时代和知识经济时代的到来,企业内部信息资料繁多冗杂,知识管理逐渐成为各大企业的重要工作之一,企业管理者无不感受到巨大的压力,怎么样将知识进行有效的管理,成为一个难点,并且随着信息不断的更迭…...
一文搞懂core-scheduling核心机制
cookie的原理借助于unsigned long型,和refcount_t引用计数器。 32位64位char *4字节8字节unsigned long4字节8字节 数据结构修改 首先看看实现core scheduling功能对数据结构有哪些修改 task_struct struct task_struct{struct rb_node core_node;unsigned long…...
IP地址在金融行业有哪些应用?
中国加入WTO以来经济得到迅速发展,金融行业随着经济发展体系越来越完善。随着西方金融公司和理念的加入中国金融行业开始多样化发展。金融行业在快速发展的同时也引发了许多弊端。如何维护挖掘客户更大需求?如何获取更多优质客户?如何提升网络…...
GT-suite v2016解决许可证过期问题(附新版liscense下载地址)
安装GT-suite v2016时遇到了如图报错的问题。当时的报错找不到了,下图是贴吧相同问题的报错图。 为了解决问题,先根据某网友的如下答复操作: 添加环境变量后仍然有相同报错。 看来需要寻找其他方法。 再尝试着卸载GT-suite v2016,…...
小红书商业笔记与普通笔记区别是什么?小红书笔记有哪几种
主攻单一平台,如何迅速打造爆文。针对软文发布类别的选择,小红书商业笔记与普通笔记区别究竟是什么,今天为大家带来的详细分析,告诉你该如何用最少的成本,做出“爆文”。1、小红书的笔记类型我们都知道,小红…...
DataWhale-统计学习方法打卡Task01
学习教材《统计学习方法(第二版)》李航 统计学习方法(第2版) by...李航 (z-lib.org).pdf https://www.aliyundrive.com/s/maJZ6M9hrTe 点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无…...
Java面试——Spring 事务
目录 1.什么是Spring 事务 2.Spring 事务的开启方式 3.Spring事务的实现方式/原理 4.事务传播机制 5.事务隔离级别 6.事务失效的原因 1.什么是Spring 事务 事务在逻辑上是一组操作,要么执行,要不都不执行。 如下: Begin; insert into…...
Python语言零基础入门教程(十九)
Python 异常处理 python提供了两个非常重要的功能来处理python程序在运行中出现的异常和错误。你可以使用该功能来调试python程序。 1、异常处理 2、断言(Assertions) python标准异常 什么是异常? 异常即是一个事件,该事件会在程序执行过程中发生&…...
重生之我是赏金猎人-SRC漏洞挖掘(一)-某SRC测试系统无脑Getshell
0x01 前言 https://github.com/J0o1ey/BountyHunterInChina 欢迎大佬们点个star 0x02 资产收集到脆弱系统 在某src挖掘过程中,本人通过ssl证书对域名资产进行了收集,通过计算域名对应ip段的权重 整理出其C段资产,进行了批量目录扫描 查看…...
Sciter 结合 PReact 实现组件公共逻辑抽离
Sciter 结合 PReact 实现组件公共逻辑抽离 下面例子是获取鼠标移动位置,将这部分逻辑进行抽离 一、使用高阶组件抽离公共逻辑 import {Component } from ./preact.js; export const HOCFactory = (Component) => {class HOC...
OpenTracing协议规范链接
一、官网链接 OpenTracing specificationhttps://opentracing.io/specification/不过目前OpenTracing项目已归档,不再维护。需要参考OpenTelemetry官网链接 Migrating from OpenTracing | OpenTelemetryBackward compatibility with OpenTracing has been a prior…...
金三银四面试必看,自动化测试如何解决日志问题
前言 前几天在员群里,有同学问了一个自动化测试实践中遇到的问题: 持续集成的自动化用例很多,测试环境日志level为debug,日志量大概40G/每天,定位问题时日志查询很慢,该怎么解决? 这个问题可…...
微信怎么开小店?【企业商家微信开店】
企业商家入局微信做营销已经是经营规划中必须做的一件事了,对于企业商家来说,最简单直接的方式就是开一个微信小店,然后通过自己宣传推广来在微信小店中成商品。那么企业商家在微信怎么开小店呢?下面内容分享给想在微信开店的企业…...
Java 中FastJson的使用【吃透FastJson】
如果不了解JSON格式,建议先看下:JSON数据格式【学习记录】 JSON序列化、反序列化JavaBean的框架有很多,最常见的Jackson、阿里巴巴开源的FastJson、谷歌的GSON、apache提供的json-lib等,下面我们主要来熟悉一下:Java语…...
造相-Z-Image-Turbo 在计算机网络教学中的应用:可视化展示协议交互角色
造相-Z-Image-Turbo:让计算机网络协议“活”起来的教学新助手 每次讲到TCP三次握手、HTTP请求响应这些概念,看着台下学生迷茫的眼神,你是不是也感到头疼?协议栈、数据包、端口号,这些抽象的名词和冰冷的箭头图&#x…...
深度解析开源工具如何实现游戏性能优化:Genshin FPS Unlocker专业实战指南
深度解析开源工具如何实现游戏性能优化:Genshin FPS Unlocker专业实战指南 【免费下载链接】genshin-fps-unlock unlocks the 60 fps cap 项目地址: https://gitcode.com/gh_mirrors/ge/genshin-fps-unlock Genshin FPS Unlocker 是一款专注于游戏性能优化的…...
NaViL-9B效果惊艳:复杂背景证件照文字识别+人像属性分析展示
NaViL-9B效果惊艳:复杂背景证件照文字识别人像属性分析展示 1. 模型能力概览 NaViL-9B作为原生多模态大语言模型,在证件照处理领域展现出惊人的能力。它不仅能够准确识别复杂背景下的文字信息,还能对人像属性进行智能分析,为证件…...
Easegress全方位监控指南:构建云原生流量可观测性系统的终极方案
Easegress全方位监控指南:构建云原生流量可观测性系统的终极方案 【免费下载链接】easegress A Cloud Native traffic orchestration system 项目地址: https://gitcode.com/gh_mirrors/eas/easegress Easegress是一个强大的云原生流量编排系统,专…...
Qwen3-VL-8B-Instruct-GGUF模型安全部署最佳实践
Qwen3-VL-8B-Instruct-GGUF模型安全部署最佳实践 1. 引言 在企业环境中部署AI模型时,安全性往往是首要考虑的因素。Qwen3-VL-8B-Instruct-GGUF作为一款强大的多模态视觉语言模型,能够处理图像和文本的复杂任务,但如果部署不当,可…...
LabelMe图像标注自动化:基于模板匹配的实现方法
LabelMe图像标注自动化:基于模板匹配的实现方法 LabelMe是一款强大的图像多边形标注工具,支持多边形、矩形、圆形、线条、点和图像级标志的标注。本文将介绍如何利用模板匹配技术实现LabelMe图像标注的自动化,帮助用户快速提升标注效率&…...
告别SVN烦恼:三步完成SVN到Git的无缝迁移
告别SVN烦恼:三步完成SVN到Git的无缝迁移 【免费下载链接】svn2git 项目地址: https://gitcode.com/gh_mirrors/sv/svn2git 在软件开发的版本控制领域,Subversion(SVN)曾是许多团队的首选工具。然而,随着分布式…...
智能客服意图识别实战:基于AI辅助开发的架构设计与避坑指南
在智能客服系统中,意图识别是决定对话能否顺畅进行的关键。简单来说,它就像客服的“耳朵”和“大脑”,需要准确听懂用户五花八门的问法,并快速判断出用户到底想干什么——是查询订单、投诉问题,还是咨询产品。然而&…...
暗黑破坏神:技术焕新与经典重构——DevilutionX的跨平台复兴之路
暗黑破坏神:技术焕新与经典重构——DevilutionX的跨平台复兴之路 【免费下载链接】devilutionX Diablo build for modern operating systems 项目地址: https://gitcode.com/gh_mirrors/de/devilutionX 在游戏产业飞速迭代的今天,如何让经典IP在现…...
Insights Imaging 安徽医科大学第一附属医院放射科吴兴旺教授等团队:基于自动化nnU-Net与影像组学的胃癌Lauren分型术前预测
01文献学习今天分享的文献是由安徽医科大学第一附属医院放射科吴兴旺教授团队联合南京医科大学第二附属医院、中国科学技术大学附属第一医院等团队于2025年2月在《Insights into Imaging》(中科院2区top,IF4.5)上发表的研究“Preoperative pr…...
