spring boot中一般如何使用线程池
在Spring Boot中,线程池作为并发编程的核心工具,对于提升应用程序性能、优化资源利用和保证系统稳定性具有重要作用。本文将详细阐述如何在Spring Boot中正确使用线程池,包括配置参数、实例化、任务提交、监控及常见问题处理等环节,并辅以代码示例,以期为开发者提供一份全面的实践指南。
一、线程池基础
线程池是一种基于池化技术管理线程的机制,其核心目标在于减少线程创建与销毁的开销,通过复用已创建的线程来处理一系列异步任务。在Java中,java.util.concurrent.ThreadPoolExecutor是实现线程池的基础类,而Spring Boot则通过封装ThreadPoolTaskExecutor或ThreadPoolTaskScheduler等组件,简化了线程池的配置和使用。
二、Spring Boot线程池配置
Spring Boot中使用线程池通常涉及以下几个关键参数的配置:
- 核心线程数(corePoolSize):线程池中始终保留的线程数量,即使它们处于空闲状态。当有新任务提交时,优先由核心线程执行。
- 最大线程数(maxPoolSize):线程池允许的最大线程数。当核心线程满载且任务队列已满时,线程池会创建额外的非核心线程来处理任务,直到达到此上限。
- 队列容量(queueCapacity):线程池所使用的任务队列大小。当核心线程全部忙碌时,新任务会被放入队列等待执行。队列类型可选,如无界队列、有界队列(如
ArrayBlockingQueue)、优先级队列(如PriorityBlockingQueue)等。 - 线程存活时间(keepAliveSeconds):非核心线程闲置超过此时间后会被回收。设置为0表示非核心线程随用随创建,随空随销毁。
- 拒绝策略(RejectedExecutionHandler):当线程池无法接受新任务时(例如队列已满且线程数达到最大值),采取的应对策略,如
AbortPolicy(抛出异常)、CallerRunsPolicy(调用者线程执行任务)、DiscardPolicy(丢弃任务)和DiscardOldestPolicy(丢弃队列中最旧的任务)等。
三、Spring Boot中线程池的实例化与配置
以下是一个使用ThreadPoolTaskExecutor的配置示例,通过Java配置类进行设置:
@Configuration
public class ThreadPoolConfig {@Bean(name = "customThreadPool")public ThreadPoolTaskExecutor threadPoolTaskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5); // 核心线程数executor.setMaxPoolSize(10); // 最大线程数executor.setQueueCapacity(20); // 队列容量executor.setKeepAliveSeconds(30); // 线程存活时间executor.setThreadNamePrefix("custom-thread-"); // 线程名前缀executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 拒绝策略return executor;}
}
四、提交任务到线程池
配置好线程池后,可以通过注入ThreadPoolTaskExecutor实例,调用其execute()或submit()方法来提交任务:
@Service
public class AsyncService {@Autowired@Qualifier("customThreadPool")private ThreadPoolTaskExecutor taskExecutor;public void executeAsyncTask(Runnable task) {taskExecutor.execute(task);}public Future<String> submitAsyncTask(Callable<String> task) {return taskExecutor.submit(task);}
}// 使用示例
@Autowired
private AsyncService asyncService;public void triggerAsyncTasks() {Runnable task1 = () -> System.out.println("Executing task 1");asyncService.executeAsyncTask(task1);Callable<String> task2 = () -> {Thread.sleep(2000);return "Task 2 result";};Future<String> futureResult = asyncService.submitAsyncTask(task2);// 异步获取结果try {String result = futureResult.get();System.out.println("Task 2 returned: " + result);} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}
}
五、监控与调整
Spring Boot对线程池的监控主要依赖于Micrometer库(如果已集成)。可以通过/actuator/metrics/threadpool.<executor-name>.<metric>端点获取线程池各项指标,如活跃线程数、队列大小、已完成任务数等。结合Prometheus、Grafana等工具,可以构建实时监控面板,以便及时发现和调整线程池性能瓶颈。
此外,应根据实际业务负载动态调整线程池参数。这可能需要结合日志分析、监控数据及压测结果,确保线程池既能充分利用系统资源,又能避免过度竞争导致性能下降或系统不稳定。
六、常见问题与注意事项
- 避免阻塞操作:提交到线程池的任务应尽量避免阻塞操作,如I/O密集型任务应使用专门的I/O线程池,以免阻塞计算线程。
- 合理设置队列:无界队列可能导致内存溢出;有界队列需配合合理的拒绝策略,防止任务堆积导致系统崩溃。
- 线程池关闭:确保在应用关闭时优雅地关闭线程池,避免资源泄漏。
- 异常处理:捕获并妥善处理线程池中任务抛出的异常,避免影响主线程或导致任务丢失。
- 线程安全:确保提交到线程池的任务及其访问的数据结构具备线程安全性。
七、总结
在Spring Boot中有效使用线程池,不仅需要理解线程池的工作原理与配置参数,还需结合实际业务场景进行合理设计与调优。通过实例化ThreadPoolTaskExecutor,配置核心参数,正确提交任务,并借助监控工具持续观察与调整,可以显著提升应用的并发处理能力与资源利用率。遵循上述原则与最佳实践,开发者能更好地驾驭线程池这一强大的并发工具,为构建高性能、高稳定性的Spring Boot应用奠定坚实基础。
相关文章:
spring boot中一般如何使用线程池
在Spring Boot中,线程池作为并发编程的核心工具,对于提升应用程序性能、优化资源利用和保证系统稳定性具有重要作用。本文将详细阐述如何在Spring Boot中正确使用线程池,包括配置参数、实例化、任务提交、监控及常见问题处理等环节࿰…...
Shader 纹理动画和顶点动画
一、内置变量--时间 要实现动画,我们需要把时间添加到计算当中,让画面可以随着时间变化而变化。在Unity Shader提供了如下关于时间的内置变量以便于在shader中访问时间实现各种动态效果。 名称类型描述_Timefloat4t是自该场景加载开始所经过的时间&…...
使用macof发起MAC地址泛洪攻击
使用macof发起MAC地址泛洪攻击 MAC地址泛洪攻击原理: MAC地址泛洪攻击是一种针对交换机的攻击方式,目的是监听同一局域网中用户的通信数据。交换机的工作核心:端口- MAC地址映射表。这张表记录了交换机每个端口和与之相连的主机MAC地址之间…...
力扣:1979. 找出数组的最大公约数(Java)
目录 题目描述:输入:输出:代码实现: 题目描述: 给你一个整数数组 nums ,返回数组中最大数和最小数的 最大公约数 。 两个数的 最大公约数 是能够被两个数整除的最大正整数。 输入: nums [2,5,6…...
电瓶车充电桩:潜藏的暴利行业,简单入门到月入万元!
近几年来,电瓶车凭借其环保、经济特点已成为居民出行的必备工具之一。而促使电瓶车快速普及的原因之一即是电瓶车充电桩的普及。如果留心观察的话,相信大家都可以看出,国内大部分小区都已安装了充电桩设备,电瓶车充电桩已实现了大…...
mac监听 linux服务器性能可视化(Grafana+Promethus+Node_exporter)
Grafana和promethus(普罗米修斯)的安装和使用 监控系统的Prometheus类似于一个注册中心,我们可以只需要配置一个Prometheus,而在其他服务器,只需要安装node_exporter,它们的数据流转就是通过exporter采集数据信息,然后告诉prometheus它的位置…...
【负载均衡在线OJ项目日记】运行功能开发
目录 前言 运行功能开发分析 获取子进程运行信息 程序运行资源限制 运行功能开发代码 前言 上篇文章我们对客户端服务器传来的临时文件进行编译,这篇文章主要对编译成功的代码在我们的服务器运行这块功能的开发。 运行功能开发分析 在运行功能开发之前我们默…...
Qt | QLineEdit 类(行编辑器)
01、上节回顾 Qt | QComboBox(组合框)02、QLineEdit 1、QLineEdit 类是 QWidget 类的直接子类,该类实现了一个单行的 输入部件,即行编辑器,见右图 2、验证器(QValidator 类)和输入掩码简介:主要作用是验证用户输入的字符是否符合验证器 的要求,即限制对用户的输入,比…...
Mamba结构的Demo源码解读
文章目录 前言一、mamba结构构建辅助函数解读1、dataclass方法解读2、Norm归一化LayerNormRMSNormRMSNorm源码 3、nn.Parameter方法解读 二、mamba原理二、mamba模型构建1、主函数入口源码解读2、Mamba类源码解读 三、ResidualBlock的mamba结构源码解读四、MambaBlock构成Resid…...
金仓面对面 | 人大金仓×安硕信息共话金融信用风险管理数字化转型之道
金仓面对面 在数字化浪潮的推动下,人大金仓携手行业先锋,共同开启一场关于创新与转型的思想盛宴——金仓面对面。这不仅是一场对话,更是一次智慧的火花碰撞,一次行业数字化转型洞察的深度挖掘。 行业精英汇聚:我们荣幸…...
JavaScript值类型与引用类型的区别
值类型(原始类型) 值类型包括:undefined、null、boolean、number、string、symbol 和 bigint。这些类型的特点是: 存储位置:值类型的数据直接存储在栈(Stack)中。复制行为:当一个值…...
每日一博 - 闲聊架构设计中的多级缓存设计
文章目录 方法论概述客户端缓存应用层缓存服务层缓存缓存设计的注意事项总结 思维导图戳这里 方法论概述 从客户端到服务层,缓存的应用广泛而重要。通过合理的缓存设计,能够有效地提高系统的性能并降低延迟。 客户端缓存 在客户端层面,浏览…...
轻松实现MySQL集群配置:一主一从与一主多从教程
在数据驱动的时代,数据库的高可用性和负载分散成为了维护在线服务稳定运行的关键。MySQL作为世界上最流行的开源关系型数据库管理系统,其集群配置是任何DBA或开发人员必须掌握的技能之一。本文将为您详细介绍如何轻松配置MySQL的一主一从和一主多从集群&…...
Leetcode刷题-(41~45)-Java
算法是码农的基本功,也是各个大厂必考察的重点,让我们一起坚持写题吧。 遇事不决,可问春风,春风不语,即是本心。 我们在我们能力范围内,做好我们该做的事,然后相信一切都事最好的安排就可以啦…...
【Android】源码解析Activity的结构分析
源码解析Activity的结构分析 目录 1、Activity、View、Window有什么关联?2、Activity的结构构建流程3 源码解析Activity的构成 3.1 Activity的Attach方法3.2 Activity的OnCreate 4、WindowManager与View的关系总结 1、一个Activity对应几个WindowManage࿰…...
小猪APP分发:重塑应用分发市场的创新力量
在移动互联网蓬勃发展的今天,应用分发平台作为连接开发者与用户的桥梁,扮演着至关重要的角色。然而,随着市场的饱和,如何在众多平台中脱颖而出,为开发者提供更宽广的舞台,同时确保用户能够便捷、安全地获取…...
区块链 | IPFS 工作原理入门
🦊原文:What is the InterPlanetary File System (IPFS), and how does it work? 🦊写在前面:本文属于搬运博客,自己留存学习。 1 去中心化互联网 尽管万维网是一个全球性的网络,但在数据存储方面&#…...
减速机齿数速算
1.齿轮相关参数 1.1 模数 , 因为 齿数*齿距 Pi*直径 所以:直径/齿数 齿距/PI 模数 国标现行标准(截止2024/5)是: GB/ 1357-2008 / ISO 54-1996 模数有国标的一个序列标准: 1.2.轴径 轴径的国标是&a…...
2万字长文:海豚调度器(DolphinScheduler)面试题深入了解
目录 海豚调度器的主要功能和特点 海豚调度器与Oozie、Azkaban等调度器相比的优势...
全双工音频对讲模块-支持空中升级、多级无线中继
SA618F30是一款高集成的大功率全双工无线音频模块,发射功率高达32dBm。该音频模块简化接口,只需外接音频功放或麦克风即可作为一个小型对讲机,方便快捷嵌入到各类手持设备中。支持多级无线中继,支持OTA空中升级。 SA618F30配备1W…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...
