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

java.util.ConcurrentModificationException 并发修改异常

目录

异常代码片段

详细说明

解决方案

使用迭代器进行遍历

使用临时集合存储结果


异常代码片段

if (ObjectUtil.isNotEmpty(candidateUsers)) {candidateUsers = candidateUsers.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());for (String candidateUser : candidateUsers) {if (ObjectUtil.isNotEmpty(candidateUser) && candidateUser.contains("${")) {try {String expressionValue = expressionService.getStrValue(extendHisprocinst.getProcessInstanceId(), candidateUser);candidateUsers.add(expressionValue);} catch (Exception e) {log.error("解析人员报错,原因:{}", ExceptionUtil.stacktraceToString(e));}}}
}

这段代码中出现ConcurrentModificationException异常的原因是,在遍历candidateUsers集合的同时对其进行了修改。

具体来说,是在遍历过程中通过candidateUsers.add(expressionValue);向集合中添加元素,这会导致ConcurrentModificationException异常。

详细说明

详细解释

1.集合的遍历机制:

  • 当你使用for-each循环遍历集合时,实际上是在使用迭代器(Iterator)来遍历集合中的元素。

  • 迭代器在遍历集合时会维护一个内部计数器,以跟踪当前遍历的位置。

  • 每次调用next()方法时,迭代器会移动到下一个位置,并返回当前位置的元素。

2.并发修改检测:

  • Java集合框架中的许多集合类(如ArrayList)在遍历期间会检查集合是否被修改过。

  • 这种检查是通过一个称为modCount的字段来实现的,每当集合被修改时(例如添加或删除元素),modCount值就会增加。

  • 迭代器有一个expectedModCount字段,它在迭代器创建时被初始化为集合的modCount值。

  • 在每次调用next()方法时,迭代器会检查expectedModCount是否等于集合的当前modCount值。

  • 如果expectedModCount与当前modCount不匹配,说明集合在遍历过程中被修改过,这时迭代器会抛出ConcurrentModificationException异常。

代码分析

  • 在这段代码中,首先使用了流操作过滤并去重candidateUsers集合,然后遍历这个集合。
  • 在遍历过程中,如果满足某个条件(即candidateUser包含${),会尝试从expressionService获取表达式的值,并将其添加回candidateUsers集合中。
  • 这种做法违反了遍历过程中的并发修改规则,因此抛出了ConcurrentModificationException异常。

解决方案

为了避免这个问题,可以采用以下几种方法之一。

使用迭代器进行遍历

使用迭代器遍历集合,并在外部循环中处理元素,避免直接修改正在遍历的集合。

这种方法避免了直接修改正在遍历的集合,而是使用迭代器来安全地访问集合中的元素。

if (ObjectUtil.isNotEmpty(candidateUsers)) {candidateUsers = candidateUsers.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());Iterator<String> iterator = candidateUsers.iterator();while (iterator.hasNext()) {String candidateUser = iterator.next();if (ObjectUtil.isNotEmpty(candidateUser) && candidateUser.contains("${")) {try {String expressionValue = expressionService.getStrValue(extendHisprocinst.getProcessInstanceId(), candidateUser);candidateUsers.add(expressionValue);} catch (Exception e) {log.error("解析人员报错,原因:{}", ExceptionUtil.stacktraceToString(e));}}}
}
 
使用临时集合存储结果

创建一个新的集合来存储处理后的结果,而不是直接修改原始集合。从而避免了ConcurrentModificationException异常。

选择其中一种方法即可解决问题。如果需要保留原始集合的内容,建议使用第二种方法(使用临时集合存储结果)。

if (ObjectUtil.isNotEmpty(candidateUsers)) {List<String> tempCandidateUsers = new ArrayList<>();candidateUsers = candidateUsers.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());for (String candidateUser : candidateUsers) {if (ObjectUtil.isNotEmpty(candidateUser) && candidateUser.contains("${")) {try {String expressionValue = expressionService.getStrValue(extendHisprocinst.getProcessInstanceId(), candidateUser);tempCandidateUsers.add(expressionValue);} catch (Exception e) {log.error("解析人员报错,原因:{}", ExceptionUtil.stacktraceToString(e));}} else {tempCandidateUsers.add(candidateUser);}}candidateUsers = tempCandidateUsers;
}
​

相关文章:

java.util.ConcurrentModificationException 并发修改异常

目录 异常代码片段 详细说明 解决方案 使用迭代器进行遍历 使用临时集合存储结果 异常代码片段 if (ObjectUtil.isNotEmpty(candidateUsers)) {candidateUsers candidateUsers.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());for (String …...

Flask数据库操作(第四阶段)

目录 Flask数据库操作一、数据库基础1.1 关系型数据库与非关系型数据库选择数据库 二、Flask-SQLAlchemy2.1 安装 Flask-SQLAlchemy2.2 创建数据库模型2.2.1 创建 Flask 应用2.2.2 定义模型 2.3 执行 CRUD 操作2.3.1 创建&#xff08;Create&#xff09;2.3.2 读取&#xff08;…...

C语言问答进阶--5、基本表达式和基本语句

赋值表达式 表达式是什么&#xff1f;表达式是由运算符和操作数组成的式子。 如下的代码 #include "iostream.h" int main() { int a1,b2,sum; cout<<(sumab)<<endl; return 0; } 那么如下的呢&#xff1f; #include "iostream.h" int mai…...

uniapp3.0实现图片上传公用组件上传uni-file-picker,uni.uploadFile

用uniapp3.0的写法组合式api&#xff0c;setup形式封装一个图片上传公用组件&#xff0c;要求 1、使用uni-file-picker选择文件 2、uni.uploadFile上传图片 3、要能支持上传接口动态化 4、支持删除如片列表中已上传项 5、可以预览已上传列表图片 6、支持动态化限制图片格…...

Unity游戏开发002

Unity游戏开发002 目录 第一章&#xff1a;Hello&#xff0c;Unity&#xff01;第二章&#xff1a;创建一个游戏体 本文目录 Unity游戏开发 Unity游戏开发002目录本文目录前言一、创建一个游戏体1. 编辑器语言设置2. 创建游戏对象的两种方法3. 快速复制和粘贴物体4. 注意事项…...

MySQL基础练习题38-每位教师所教授的科目种类的数量

目录 题目 准备数据 分析数据 总结 题目 查询每位老师在大学里教授的科目种类的数量。 准备数据 ## 创建库 create database db; use db;## 创建表 Create table If Not Exists Teacher (teacher_id int, subject_id int, dept_id int)## 向表中插入数据 Truncate table…...

haproxy 原理+实战

haproxy 1 haproxy简介1.1 定义1.2 原理讲解1.3 HAProxy的优点&#xff1a; 2. haproxy的基本部署2.1 实验环境2.1.2 haproxy主机配置2.1.3 webserver1配置2.1.4 webserver2配置 3. haproxy的全局配置4. haproxy代理参数5. haporxy的热处理6.haproxy的算法6.1 静态算法6.1.1sta…...

OSPF进阶

一、LSA详解 Type&#xff1a;LSA的类型&#xff08;1、2、3、4、5、7类&#xff09; link-state-ID&#xff1a;链路状态表示符 ADV router&#xff1a;产生该LSA的路由器 age&#xff1a;老化时间 Metric&#xff1a;开销值&#xff0c;一般都为ADV router到达该路由的开…...

SuccBI+低代码文档中心 — 可视化分析(仪表板)(下)

制作仪表板 引入数据模型 仪表板所需模型已经在数据模块中准备好&#xff0c;可以将对应模型表添加到数据模型中。提供了两种添加方式&#xff1a; 在数据栏中点击添加按钮&#xff0c;在弹出框中通过搜索或直接在其所在目录下选中该模型&#xff0c;点击确定。 点击数据按钮…...

前端创作纪念日

机缘 作者也是一名新人大学生&#xff0c;在学习过程中总是get不到专业的知识体系&#xff0c;机缘巧合下了解通过md文档记笔记然后分享在各大博客平台上面&#xff0c;可以吸引社区博客朋友们的关注的鼓励&#xff0c;使得直接创作努力学习的心更加澎湃。 实战项目中的经验分…...

丰收季遇科技之光:北斗卫星导航引领现代农业新篇章

在这个金风送爽、硕果累累的丰收时节&#xff0c;广袤的田野上洋溢着农民们欢声笑语&#xff0c;每一粒饱满的果实都是大自然与辛勤耕耘者的共同馈赠。而在这片希望的田野上&#xff0c;一项科技革命的浪潮正悄然改变着传统农业的面貌——北斗卫星导航系统&#xff0c;正以它精…...

解决windows7虚拟机安装不了vmtools问题

安装不了vmtools问题所在&#xff1a; 没打补丁 ​ 打补丁问题 补丁在本地下载之后无法传到win7虚拟机中 补丁获取 补丁链接如下&#xff1a; https://catalog.s.download.windowsupdate.com/c/msdownload/update/software/secu/2019/09/windows6.1-kb4474419-v3-x64_b5614c6…...

Microsoft VBA Excel VBA函数学习笔记——数据切分熟练度+1

问题场景 123456Stock006006006002002002MarketUSUSUSUSUSUSWeight0.010.1090.2280.2220.2390.72CurrencyEURUSDCNYEURUSDCNYTerm10.0740.0820.0120.0470.0580.067Term20.040.020.010.070.0580.067Term30.0540.0520.0140.0870.0480.017Term40.0710.0840.0020.0170.0180.097………...

uniapp获取swiper中子组件的内容高度

swiper有默认高度,如果不单独设置一个具体高度&#xff0c;swiper后面的内容将不会展示 这里展示的例子是: swiper中放有一个子组件,想要完整展示子组件的内容&#xff0c;swiper就需要获取到子组件的内容高度并设置 <!-- 注意: 这里的单位是 px,不是rpx --><swiper…...

基于计算机爱心小屋公益机构智慧管理(源码+论文+部署讲解等)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台的优…...

详细学习PyQt5的样式表与界面美化

Pyqt5相关文章: 快速掌握Pyqt5的三种主窗口 快速掌握Pyqt5的2种弹簧 快速掌握Pyqt5的5种布局 快速弄懂Pyqt5的5种项目视图&#xff08;Item View&#xff09; 快速弄懂Pyqt5的4种项目部件&#xff08;Item Widget&#xff09; 快速掌握Pyqt5的6种按钮 快速掌握Pyqt5的10种容器&…...

遥控器android设备键值原理

输入设备触发事件发送数据-》将键值映射到内核中预定义的键值-》上报键值&#xff0c;通过kl文件将按键码转化为标签字符串 内核获取键码&#xff0c;扫描码 按键标签其实对应的也是一个按键码。与kernel上报的按键码不同&#xff0c;按键标签所对应的按键…...

零基础也想学编程?Java零基础入门学习路线 + Java教程已准备好!

本文作者&#xff1a;程序员鱼皮 免费编程学习 - 编程导航网&#xff1a;https://www.code-nav.cn 符号表 可以通过路线知识点前的表情字符&#xff0c;根据自己的实际情况选择学习&#xff1a; &#x1f315; 所有同学必须学习&#xff01;&#xff01;&#xff01;&#x1…...

Avnet ZUBoard 1CG开发板上手—深度学习新选择

Avnet ZUBoard 1CG 开发板上手—深度学习新选择 摘要 本文主要介绍了 Avnet ZUBoard 1CG 开发板的特性、架构、硬件单元等概念&#xff0c;并对如何使用以太网接口和串口连接开发板进行基本介绍&#xff0c;同时辅以两个应用例程演示其功能。 原文链接&#xff1a; FreakSt…...

C/C++复习 day1

C/C复习 day1 文章目录 C/C复习 day1前言一、C语言1.memcpy函数2.memmove函数3.strstr函数4.宏定义的函数5.大小端的介绍以及判断 二、C入门基础1.C是如何支持函数重载的&#xff1f;2.建议用const enum inline去替代宏 三、C类和对象1.类大小的计算2.移动构造和移动赋值1.右值…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

Windows安装Miniconda

一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...