SpringBoot3使用CompletableFuture时java.util.ConcurrentModificationException异常解决方案

问题描述

在Spring Boot 3项目中,使用CompletableFuture进行异步编程时,偶发{"code":500,"msg":"java.util.ConcurrentModificationException"}异常,但代码中并未直接操作ListCopyOnWriteArrayList等集合类。

异常原因分析

  1. 默认线程池问题
    CompletableFuture.supplyAsync()runAsync()默认使用ForkJoinPool.commonPool(),该池为全局共享线程池。当多个异步任务竞争共享资源(如Spring容器管理的非线程安全Bean)时,可能引发并发冲突。

  2. 隐式共享状态修改
    即使未显式操作集合,若异步任务中调用的方法间接修改了某个共享状态(如缓存、静态变量、非线程安全的第三方组件),也会触发此异常。


解决方案及代码实现

通过显式指定线程池+结合@Async注解的双重防护策略,可有效解决因线程竞争导致的ConcurrentModificationException。核心思路是通过资源隔离切断并发冲突路径,同时提高系统异步调用的可控性。

结合@Async注解强化异步隔离

配置@Async专用线程池ThreadPoolTaskExecutor

ThreadPoolTaskExecutor 是 Spring 框架中的一个工具类,用于管理线程池。它是 org.springframework.scheduling.concurrent 包的一部分,提供了一种方便的方式来处理并发任务,特别是在需要执行大量短期任务的情况下。

它的核心功能是基于 Java 的 java.util.concurrent.ThreadPoolExecutor,但通过 Spring 进行了进一步的封装和简化,以便于在 Spring 应用程序中更轻松地配置和使用。ThreadPoolTaskExecutor 提供以下功能:

  1. 线程池管理:可以通过配置核心线程数、最大线程数、队列容量等来优化资源使用。

  2. 任务调度:在多线程环境中按需分配和执行任务。

  3. 支持动态调整:可以根据实际需求动态调整线程池的属性,比如增减线程数量。

  4. 与 Spring 的集成:与 Spring 的上下文很好地结合,可以轻松注入到其他组件中。

它常用于需要高效地处理并发任务的场景,如异步任务执行、事件处理、任务调度等。

@Configuration
@EnableAsync // 启用异步支持
public class AsyncConfig {@Bean("asyncTaskExecutor")public Executor asyncTaskExecutor() {//Powered by Moshow@https://zhengkai.blog.csdn.net/ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5);  // 核心线程数executor.setMaxPoolSize(10); // 最大线程数executor.setQueueCapacity(25); // 队列容量executor.setThreadNamePrefix("Async-");executor.initialize();return executor;}
}
在Service层使用@Async注解并使用CompletableFuture<T>包装返回

当需要执行任务时,可以通过注入 ThreadPoolTaskExecutor 来提交任务,线程池会根据配置进行调度和处理。

在 Spring 中使用 @Async 注解时,可以通过指定一个自定义的 ThreadPoolTaskExecutor 来管理异步方法的执行线程池。

@Service
public class BusinessService {@Async("asyncTaskExecutor") // 指定线程池public CompletableFuture<String> doInternalOperation() {//Powered by Moshow@https://zhengkai.blog.csdn.net/// 方法内部可能存在隐式共享状态操作return CompletableFuture.completedFuture("Result");}
}

关键原理说明

  1. 线程池隔离
    通过自定义线程池避免全局池竞争,确保异步任务资源独立,降低并发冲突概率。

  2. 双层级异步控制

    • 外层CompletableFuture控制任务提交流程

    • 内层@Async方法实现业务逻辑与线程池的深度绑定
      双重隔离机制彻底切断共享状态污染路径。

  3. Spring上下文传播
    使用@Async+线程池时,Spring会自动传递上下文(如事务、SecurityContext),而直接使用CompletableFuture需手动处理。


注意事项

  • 避免混合使用不同线程池
    确保CompletableFuture@Async使用相同或逻辑隔离的线程池配置。

  • 监控线程池状态
    建议通过Micrometer等工具监控线程池队列堆积、拒绝次数等指标。

  • 异常处理
    CompletableFuture链式调用.exceptionally()处理异常,@Async方法可定义AsyncUncaughtExceptionHandler

示例代码已通过Spring Boot 3.2.x验证,强烈建议根据infrastructure情况和实际业务需要调整线程池参数。

Powered by Moshow@https://zhengkai.blog.csdn.net/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/38272.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

细说卫星导航:测距定位原理

测距定位原理 1. 伪距测量技术 核心原理&#xff1a;卫星发射信号&#xff0c;用户接收并记录传播时间&#xff0c;乘以光速得到距离&#xff08;伪距&#xff09;。 技术细节&#xff1a; 信号传播路径分析 信号结构&#xff1a; 卫星信号包含三部分&#xff1a; 载波&…

Linux系统管理与编程09:任务驱动综合应用

兰生幽谷&#xff0c;不为莫服而不芳&#xff1b; 君子行义&#xff0c;不为莫知而止休。 [环境] windows11、centos9.9.2207、zabbix6、MobaXterm、Internet环境 [要求] zabbix6.0安装环境&#xff1a;Lamp&#xff08;linux httpd mysql8.0 php&#xff09; [步骤] 5 …

RAG(Retrieval-Augmented Generation)基建之PDF解析的“魔法”与“陷阱”

嘿&#xff0c;亲爱的算法工程师们&#xff01;今天咱们聊一聊PDF解析的那些事儿&#xff0c;简直就像是在玩一场“信息捉迷藏”游戏&#xff01;PDF文档就像是个调皮的小精灵&#xff0c;表面上看起来规规矩矩&#xff0c;但当你想要从它那里提取信息时&#xff0c;它就开始跟…

RK3568 I2C底层驱动详解

前提须知&#xff1a;I2C协议不懂的话就去看之前的内容吧&#xff0c;这个文章需要读者一定的基础。 RK3568 I2C 简介 RK3568 支持 6 个独立 I2C: I2C0、I2C1、I2C2、I2C3、I2C4、I2C5。I2C 控制器支持以下特性: ① 兼容 i2c 总线 ② AMBA APB 从接口 ③ 支持 I2C 总线主模式…

UNIX网络编程笔记:基本TCP套接字编程

一、socket函数 一、socket函数核心参数与协议组合 函数原型与基本功能 #include <sys/socket.h> int socket(int family, int type, int protocol);• 功能&#xff1a;创建通信端点&#xff08;套接字&#xff09;&#xff0c;返回描述符供后续操作。 • 返回值&#…

JSON在AutoCAD二次开发中应用场景及具体案例

配置文件的读取 在AutoCAD插件开发中&#xff0c;可能需要生成、修改、读取配置文件中一些参数或设置。JSON格式的配置文件易于编写和修改&#xff0c;且可以方便地反序列化为对象进行使用。 运行后效果如下 using Autodesk.AutoCAD.ApplicationServices; using Autodesk.Au…

自由学习记录(46)

CG语法的数据类型 // uint : 无符号整数&#xff08;32位&#xff09; // int : 有符号整数&#xff08;32位&#xff09; // float : 单精度浮点数&#xff08;32位&#xff09;&#xff0c;通常带后缀 f&#xff08;如 1.0f&#xff09; // half : 半精度浮…

解决Selenium滑动页面到指定元素,点击失效的问题

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:Java入门知识&#x1f649; &#x1f439;今日诗词:君失臣兮龙为鱼&#xff0c;权归臣兮鼠变虎&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主&#x1f64f; ⛳️点赞 ☀️收藏⭐️关注&#x1f4…

Vue基础

目录 -Vue基础- 1、插值表达式 {{}} 2、Vue核心特性&#xff1a;响应式 3、开发者工具Vue Devtools(极简插件下载) 4、Vue指令 v-text v-html v-bind v-on v-if v-show v-for v-model 5、Vue指令修饰符 .stop .prevent .capture .self .once .enter、.tab、…

收数据花式画图plt实战

目录 Python plt想把纵坐标化成对数形式代码 子图ax. 我又有ax scatter&#xff0c;又有ax plot&#xff0c;都要去对数 数字接近0&#xff0c;取对数没有定义&#xff0c;怎么办 创建数据 添加一个小的常数以避免对数未定义的问题 创建一个figure和一个子图ax 在子图a…

二项式分布(Binomial Distribution)

二项式分布&#xff08;Binomial Distribution&#xff09; 定义 让我们来看看玩板球这个例子。假设你今天赢了一场比赛&#xff0c;这表示一个成功的事件。你再比了一场&#xff0c;但你输了。如果你今天赢了一场比赛&#xff0c;但这并不表示你明天肯定会赢。我们来分配一个…

【算法工程】大模型开发之windows环境的各种安装

1. 背景 最近由于研究需要&#xff0c;我购置了两块3090显卡&#xff0c;以便在家中进行一些小规模的实验。为此&#xff0c;还更换了主机。当然&#xff0c;新系统上少不了要安装各种开发环境。从开发体验来看&#xff0c;macOS无疑更为流畅&#xff0c;但为了确保所有环境都能…

论文阅读笔记:Denoising Diffusion Probabilistic Models (2)

接论文阅读笔记&#xff1a;Denoising Diffusion Probabilistic Models (1) 3、论文推理过程 扩散模型的流程如下图所示&#xff0c;可以看出 q ( x 0 , 1 , 2 ⋯ , T − 1 , T ) q(x^{0,1,2\cdots ,T-1, T}) q(x0,1,2⋯,T−1,T)为正向加噪音过程&#xff0c; p ( x 0 , 1 , …

vscode查看文件历史git commit记录

方案一&#xff1a;GitLens 在vscode扩展商店下载GitLens 选中要查看的文件&#xff0c;vscode界面右上角点击GitLens的图标&#xff0c;选择Toggle File Blame 界面显示当前打开文件的所有修改历史记录 鼠标放到某条记录上&#xff0c;可以看到记录详情&#xff0c;选中O…

【数据挖掘】Python基础环境安装配置

【数据挖掘】Python基础环境安装配置 一、摘要二、安装Python3.13.2三、安装Jupyter Notebook四、安装Numpy和Pandas以及matplotlib五、安装scikit-learn库和seaborn库 一、摘要 本文主要介绍如何在Windows上安装Python3.13.2&#xff0c;然后基于该Python版本安装Jupyter not…

DeepSeek写打台球手机小游戏

DeepSeek写打台球手机小游戏 提问 根据提的要求&#xff0c;让DeepSeek整理的需求&#xff0c;进行提问&#xff0c;内容如下&#xff1a; 请生成一个包含以下功能的可运行移动端打台球小游戏H5文件&#xff1a; 要求 可以重新开始游戏 可以暂停游戏 有白球和其他颜色的球&am…

SpringMVC的执行流程剖析和源码跟踪

目录 一、常用组件:1、DispatcherServlet2、HandlerMapping3、Handler4、HandlerAdapter:5、ViewResolver6、View 二、SpringMVC的执行流程:1、流程图 在这里插入图片描述2、文字解析流程图3、ContextLoaderListener 三、源码跟踪1、doService()方法2、doDispatch()方法逻辑分解…

LeetCode hot 100 每日一题(13)——73. 矩阵置零

这是一道难度为中等的题目&#xff0c;让我们来看看题目描述&#xff1a; 给定一个 _m_ x _n_ 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 提示&#xff1a; m matrix.lengthn matrix[0].length1 < m, n …

ubuntu 解挂载时提示 “umount: /home/xx/Applications/yy: target is busy.”

问题如题所示&#xff0c;我挂载一个squanfs文件系统到指定目录&#xff0c;当我使用完后&#xff0c;准备解挂载时&#xff0c;提示umount: /home/xx/Applications/yy: target is busy.&#xff0c;具体的如图所示&#xff0c; 这种提示通常是表明这个路径的内容正在被某些进…

跟着StatQuest学知识06-CNN进行图像分类

目录 一、CNN特点 二、CNN应用于图像分类 &#xff08;一&#xff09;使用过滤器 &#xff08;二&#xff09;通过ReLU激活函数 &#xff08;三&#xff09;应用新的滤波器&#xff08;池化&#xff09; &#xff08;四&#xff09;输入 &#xff08;五&#xff09;输出…