Java线程池ThreadPoolExecutor应用(Spring Boot微服务)
记录:475
场景:在Spring Boot微服务中使用Java线程池ThreadPoolExecutor。实现Runnable接口提交线程任务到线程池。
版本:JDK 1.8,Spring Boot 2.6.3。
1.使用注解配置线程池ThreadPoolExecutor
(1)说明
ThreadPoolExecutor,全称:java.util.concurrent.ThreadPoolExecutor。
使用@Bean("threadPoolExecutorHz")注解把线程池注入到Spring IOC容器中。
(2)代码
@Configuration
public class ThreadPoolConfig {@Bean("threadPoolExecutorHz")public ThreadPoolExecutor threadPoolExecutor(){ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(8,16,10,TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),new ThreadPoolExecutor.CallerRunsPolicy());return threadPoolExecutor;}
}
(3)线程参数
corePoolSize: the number of threads to keep in the pool, even if they are idle, unless allowCoreThreadTimeOut is set
maximumPoolSize: the maximum number of threads to allow in the pool
keepAliveTime: when the number of threads is greater than the core, this is the maximum time that excess idle threads will wait for new tasks before terminating.
unit: the time unit for the keepAliveTime argument
workQueue: the queue to use for holding tasks before they are executed. This queue will hold only the Runnable tasks submitted by the execute method.
handler: the handler to use when execution is blocked because the thread bounds and queue capacities are reached
2.实现Runnable接口的线程任务类
(1)说明
提交给线程池任务,需实现Runnable接口。
Runnable接口的run方法里面就是线程具体执行的业务逻辑。
(2)代码
public class SportContestExecutor implements Runnable {private SportContest sportContest;public SportContestExecutor(SportContest sportContest) {this.sportContest = sportContest;}@Overridepublic void run() {String eventName = sportContest.getTaskDto().getEventName();System.out.println("【线程: "+Thread.currentThread().getName()+",在直播: "+eventName+"】");this.sportContest.holdSportGame();}
}
3.线程具体业务逻辑类
(1)说明
本例线程执行的业务逻辑实现类均继承于同一个抽象类。因此,在Runnable接口的线程任务类中是基于抽象类编程。
(2)抽象类SportContest
全称:com.hub.example.p1.contest.SportContest
代码:
public abstract class SportContest {//赛事任务private TaskDto taskDto;//开场仪式public abstract String announceStart();//举行比赛public abstract ResultDto playGame();//颁奖仪式public abstract String announceEnd(ResultDto resultDto);//举行体育赛事public String holdSportGame() {String result01 = announceStart();ResultDto result02 = playGame();String result03 = announceEnd(result02);return result03;}public TaskDto getTaskDto() {return taskDto;}public void setTaskDto(TaskDto taskDto) {this.taskDto = taskDto;}
}
(3)实现类BadmintonContest
全称:com.hub.example.p1.contest.impl.BadmintonContest
代码:
public class BadmintonContest extends SportContest {public BadmintonContest(TaskDto taskDto){this.setTaskDto(taskDto);}@Overridepublic String announceStart() {TaskDto taskDto = this.getTaskDto();System.out.println("举行羽毛球比赛入场仪式:");System.out.println("羽毛球比赛入场仪式步骤一: "+taskDto.getEventName()+"队员入场.");System.out.println("羽毛球比赛入场仪式步骤二: 裁判员、教练员等各就各位.");return "羽毛球比赛进行中";}@Overridepublic ResultDto playGame() {TaskDto taskDto = this.getTaskDto();System.out.println("举行羽毛球比赛: "+taskDto.getContent()+",选手们在奋力搏击.");return ResultDto.builder().teamName("中国羽毛球队").content("男单决赛冠军").build();}@Overridepublic String announceEnd(ResultDto resultDto) {System.out.println("举行羽毛球比赛颁奖仪式: ");System.out.println("羽毛球比赛颁奖步骤一: 为"+resultDto.getTeamName()+resultDto.getContent()+"颁发金牌.");System.out.println("羽毛球比赛颁奖步骤二: 升中华人民共和国国旗,奏中华人民共和国国歌.");return "羽毛球比赛圆满结束";}
}
(4)实现类DivingContest
全称:com.hub.example.p1.contest.impl.BadmintonContest
代码:
public class DivingContest extends SportContest {public DivingContest(TaskDto taskDto) {this.setTaskDto(taskDto);}@Overridepublic String announceStart() {TaskDto taskDto = this.getTaskDto();System.out.println("举行跳水比赛入场仪式:");System.out.println("跳水比赛入场仪式步骤一: "+taskDto.getEventName()+"队员入场.");System.out.println("跳水比赛入场仪式骤二: 裁判员、教练员等各就各位.");return "跳水比赛进行中";}@Overridepublic ResultDto playGame() {TaskDto taskDto = this.getTaskDto();System.out.println("举行跳水比赛: " + taskDto.getContent() + ",姑娘们在冲刺记录.");return ResultDto.builder().teamName("中国跳水队").content("女子10米台跳板决赛冠军").build();}@Overridepublic String announceEnd(ResultDto resultDto) {System.out.println("跳水比赛举行颁奖仪式: ");System.out.println("跳水比赛举行颁奖仪式步骤一: 为"+resultDto.getTeamName()+resultDto.getContent()+"颁发金牌.");System.out.println("跳水比赛举行颁奖仪式步骤二: 升中华人民共和国国旗,奏中华人民共和国国歌.");return "跳水比赛圆满结束";}
}
4.把Runnable接口的线程任务类提交到线程池
(1)说明
Runnable接口的线程任务类需提交到线程池才能具体执行。
(2)代码
@Component("sportWorker01")
public class SportWorker01 {/*** 自动注入线程池* */@Autowiredprivate ThreadPoolExecutor threadPoolExecutor;/*** 把线程任务提交到线程池*/public void holdGame() {SportContest tableTennis = createBean("com.hub.example.p1.contest.impl.BadmintonContest",TaskDto.builder().eventName("羽毛球球比赛").content("男单决赛").build());SportContestExecutor executor01= new SportContestExecutor(tableTennis);SportContest swimming = createBean("com.hub.example.p1.contest.impl.DivingContest",TaskDto.builder().eventName("跳水比赛").content("女子10米台跳板决赛").build());SportContestExecutor executor02= new SportContestExecutor(swimming);threadPoolExecutor.execute(executor01);ThreadUtil.sleep(1000);threadPoolExecutor.execute(executor02);}/*** 使用Java反射方式创建对象*/public SportContest createBean(String className, TaskDto params) {try {Class<?> clazz = Class.forName(className);Constructor<?> constructor = clazz.getConstructor(TaskDto.class);SportContest sportContest = (SportContest) constructor.newInstance(params);return sportContest;} catch (Exception e) {return null;}}
}
5.测试示例
(1)说明
直接在SpringBoot的启动类的main函数中测试。
在执行完成SpringApplication.run(Example212Application.class)后,SpringBoot的环境已经创建完成。
(2)代码
@SpringBootApplication
public class Example212Application {public static void main(String[] args) {SpringApplication.run(Example212Application.class);SportWorker01 sportWorker01 = SpringUtil.getBean("sportWorker01");sportWorker01.holdGame();}
}
(3)输出结果
【线程: pool-1-thread-1,在直播: 羽毛球球比赛】
举行羽毛球比赛入场仪式:
羽毛球比赛入场仪式步骤一: 羽毛球球比赛队员入场.
羽毛球比赛入场仪式步骤二: 裁判员、教练员等各就各位.
举行羽毛球比赛: 男单决赛,选手们在奋力搏击.
举行羽毛球比赛颁奖仪式:
羽毛球比赛颁奖步骤一: 为中国羽毛球队男单决赛冠军颁发金牌.
羽毛球比赛颁奖步骤二: 升中华人民共和国国旗,奏中华人民共和国国歌.
【线程: pool-1-thread-2,在直播: 跳水比赛】
举行跳水比赛入场仪式:
跳水比赛入场仪式步骤一: 跳水比赛队员入场.
跳水比赛入场仪式骤二: 裁判员、教练员等各就各位.
举行跳水比赛: 女子10米台跳板决赛,姑娘们在冲刺记录.
跳水比赛举行颁奖仪式:
跳水比赛举行颁奖仪式步骤一: 为中国跳水队女子10米台跳板决赛冠军颁发金牌.
跳水比赛举行颁奖仪式步骤二: 升中华人民共和国国旗,奏中华人民共和国国歌.
6.辅助实体类
(1)说明
在实体类中使用注解@Data等来自lombok-1.18.24.jar。
(2)TaskDto
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class TaskDto implements Serializable {//赛事名称private String eventName;//活动内容private String content;
}
(3)ResultDto
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ResultDto implements Serializable {//竞赛队伍private String teamName;//比赛成绩private String content;
}
以上,感谢。
2023年9月13日
相关文章:
Java线程池ThreadPoolExecutor应用(Spring Boot微服务)
记录:475 场景:在Spring Boot微服务中使用Java线程池ThreadPoolExecutor。实现Runnable接口提交线程任务到线程池。 版本:JDK 1.8,Spring Boot 2.6.3。 1.使用注解配置线程池ThreadPoolExecutor (1)说明 ThreadPoolExecutor,…...
QT5|C++|通过信号槽机制实现进度条更新
背景:最近在写一个删除90天数据显示进度的功能,实现思路是:通过信号槽捕获当前进度值实现。 备注:点击start按钮,开始更新进度条,直到100(每隔1s进行更新)举个栗子: 1、…...

什么是智能推荐?智能推荐的原理是什么?
一、智能推荐的魔力 2020年的愚人节晚间,罗永浩在抖音带货,相信你也被刷屏了吧。3小时的直播过程中,22款产品轮番出场,最终首播支付交易总额突破1.1亿、整场直播观看总人数超过4800万、总销售件数逾91万,粉丝打赏音浪…...

Windows下的Elasticsearch-head安装
Windows下的Elasticsearch-head安装 参考:https://gitcode.net/mirrors/mobz/elasticsearch-head 需要用到 npm 命令,这里可以提前下载安装下Node.js 即可自动安装npm; Node.js 下载安装地址:https://nodejs.org/en/download # 进…...
两台服务器间进行文件传输
目录 方法1:使用SCP 方法2:使用rsync 使用SSH密钥 两台服务器之间进行文件传输通常可以使用SCP(Secure Copy Protocol)或rsync命令。这两种方法都是在UNIX和Linux系统上常用的工具,用于安全地复制文件和目录。以下是…...

研究生选控制嵌入式还是机器视觉好?
研究生选控制嵌入式还是机器视觉好? 我是嵌入式/硬件方向转的算法,现在是公司的算法负责人,如果再让我选一次,我是不会再选嵌入式方 向,嵌入式如果只做技术是没前途的。 你要是有一定自学能力,能自己在学校…...

SecureCRT SSH与FTP连接中文乱码
1、首先要保证服务端环境变量是UTF-8编码的 LANG”zh_CN.UTF-8″ 2、会话里面配置好字符编码:UTF-8 SSH会话的窗口就可以正常显示中文了,效果如下 3、打开FTP或者SFTP时进行文件传输时,列表窗口里面还是乱码,需要把SecureCRT安…...

OSI七层网络参考模型与数据流通过程
OSI七层网络参考模型 文章目录 OSI七层网络参考模型1. OSI参考模型初步了解2. OSI参考模型理解3. 数据流通的过程 1. OSI参考模型初步了解 OSI,英文为Open System Interconnect,意为开放式系统互连,国际化标准组织(ISO)指定了OSI模型&#x…...

数字孪生行业相关政策梳理--工业领域相关政策(可下载)
自2021年国家“十四五”规划纲要提出“探索建设数字孪生城市”以来,国家发展和改革委员会、工业和信息化部、住房和城乡建设部、水利部、农业农村部等部门纷纷出台政策,大力推动数字孪生在千行百业的落地发展。这些政策不仅为数字孪生的应用提供了广阔的…...

【工具】咸鱼之王辅助小助手来了!
自动答题的视频演示:【工具】咸鱼之王辅助小助手来了!_哔哩哔哩_bilibili 刚开始搞,还没来得及做界面,目前只做了自动答题。 欢迎感兴趣的大佬一起来开发~...

黑马JVM总结(十)
(1)直接内存_基本使用 下面我们看一下使用了ByteBuffer直接内存,大文件的读写效率是非常的高 Java本身并不具备磁盘读写的能力,它需要调用操作系统的函数,需要从java的方法内部调用本地方法操作系统的方法,…...

JPEG、GIF动图可以转换成SVG、Eps格式的矢量图吗?
在进行图片设计的过程中,我们可能需要很多不同格式的图片,例如 JPG、PNG、BMP 和 GIF 位图图像,怎么将这些图片转换成矢量图呢?一款功能强大的应用程序,能够轻松将位图图片转换成矢量图输出。Vector Magic会帮你进行自…...

数据结构与算法的力量:编写更高效的代码
文章目录 为什么数据结构和算法重要?1. 提高性能2. 节省资源3. 解决复杂问题4. 改进代码质量 常见数据结构和算法数据结构1. 数组(Array)2. 链表(Linked List)3. 栈(Stack)4. 队列(Q…...

Python批量统计pdf中“中文”字符的个数
之前的文章提供了批量识别pdf中英文的方法,详见【python爬虫】批量识别pdf中的英文,自动翻译成中文上。以及自动pdf英文转中文文档,详见【python爬虫】批量识别pdf中的英文,自动翻译成中文下。以及Python统计pdf中英文单词的个数。 本文实现Python统计pdf中中文字符的…...

LeetCode的第 363 场周赛——记录+补题
研究生生涯第一次打力扣周赛——3题 1. 计算 K 置位下标对应元素的和 class Solution { public:int cnt(int x){int sum 0;while (x) {sum ((x%2)?1:0);x/2;}return sum;}int sumIndicesWithKSetBits(vector<int>& nums, int k) {int n nums.size();int ans 0…...

【网络协议】Http-上
Http请求结构: 结构图1: 实验解析请求报文: 1.在Edge浏览器上输入ip地址端口号文件资源,也就是下图中的120.XX.139.29:8888/A/B/c.html 2.我的程序接收到了一个没有有效载荷的http请求(呼应上面的结构图1),如下 GET …...
Langchain-chatchat本地部署
Langchain-chatchat本地部署 参考官网 环境配置 conda安装 minicoda下载地址 安装时注意勾选上添加环境变量。安装完成之后使用conda --version测试一下版本。 环境创建 先配置一下conda的镜像地址(使用阿里的靠谱一些),这里要修改一下…...
SQL故障和排查解决浅析
MySQL长连接 MySQL长连接是指应用程序与MySQL数据库之间的连接在执行完一个操作后不会立即关闭,而是保持活动状态以供后续使用。这种连接模式在某些情况下可以提高性能,但也可能导致一些问题。以下是MySQL长连接的一些现象和排查方法: 现象…...

基础算法--双指针算法
双指针算法 1.基本介绍 严格的来说,双指针只能说是是算法中的一种技巧。 双指针指的是在遍历对象的过程中,不是普通的使用单个指针进行访问,而是使用两个相同方向(快慢指针)或者相反方向(对撞指针&#…...

企业工程项目管理系统源码(三控:进度组织、质量安全、预算资金成本、二平台:招采、设计管理)
工程项目管理软件(工程项目管理系统)对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营,全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&am…...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...

c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

rknn toolkit2搭建和推理
安装Miniconda Miniconda - Anaconda Miniconda 选择一个 新的 版本 ,不用和RKNN的python版本保持一致 使用 ./xxx.sh进行安装 下面配置一下载源 # 清华大学源(最常用) conda config --add channels https://mirrors.tuna.tsinghua.edu.cn…...

C# winform教程(二)----checkbox
一、作用 提供一个用户选择或者不选的状态,这是一个可以多选的控件。 二、属性 其实功能大差不差,除了特殊的几个外,与button基本相同,所有说几个独有的 checkbox属性 名称内容含义appearance控件外观可以变成按钮形状checkali…...