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

Java中并发修改异常如何处理

在 Java 中,ConcurrentModificationException(并发修改异常) 是遍历集合时最常见的错误之一。它发生在迭代过程中直接修改集合结构(添加/删除元素)时,与是否多线程无关。以下是详细的处理方案:


一、异常触发场景

List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));// 会抛出 ConcurrentModificationException
for (String s : list) {if ("B".equals(s)) {list.remove(s); // 直接调用集合的 remove()}
}

二、解决方案(单线程环境)

1. 使用 Iterator.remove()(推荐)
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {String s = iterator.next();if ("B".equals(s)) {iterator.remove(); // 安全删除当前元素}
}
2. Java 8+ 使用 removeIf()
list.removeIf(s -> "B".equals(s)); // 一行代码解决
3. 使用 CopyOnWriteArrayList(读多写少场景)
List<String> list = new CopyOnWriteArrayList<>(Arrays.asList("A", "B", "C"));
for (String s : list) {if ("B".equals(s)) {list.remove(s); // 安全但性能较低(每次修改复制整个数组)}
}
4. 遍历时记录待删元素,遍历后统一删除
List<String> toRemove = new ArrayList<>();
for (String s : list) {if ("B".equals(s)) {toRemove.add(s);}
}
list.removeAll(toRemove);
5. 使用下标遍历(仅适用于 ArrayList 等随机访问集合)
for (int i = 0; i < list.size(); i++) {String s = list.get(i);if ("B".equals(s)) {list.remove(i);i--; // 修正索引}
}

三、解决方案(多线程环境)

1. 使用并发集合类
// 线程安全的 List
List<String> list = Collections.synchronizedList(new ArrayList<>());// 遍历时需手动同步
synchronized (list) {Iterator<String> it = list.iterator();while (it.hasNext()) {String s = it.next();// 操作元素}
}
2. 使用 java.util.concurrent 包中的集合
// 高性能并发 List
List<String> list = new CopyOnWriteArrayList<>();// 并发 Map
Map<String, String> map = new ConcurrentHashMap<>();
3. 使用锁机制
List<String> list = new ArrayList<>();
ReentrantLock lock = new ReentrantLock();// 写操作加锁
lock.lock();
try {list.add("X");
} finally {lock.unlock();
}// 遍历时加锁
lock.lock();
try {for (String s : list) { /* ... */ }
} finally {lock.unlock();
}

四、关键预防原则

  1. 禁止在遍历中直接修改集合
    使用 iterator.remove() 是唯一安全的修改方式。

  2. 多线程环境优先选并发集合
    ConcurrentHashMap > Collections.synchronizedMap()
    CopyOnWriteArrayList > Collections.synchronizedList()

  3. Java 8+ 优先使用 Stream API

    list = list.stream().filter(s -> !"B".equals(s)).collect(Collectors.toList());
    
  4. 避免在迭代中调用会修改集合的方法
    包括:add(), remove(), clear(), addAll() 等。


五、常见误区

方案问题推荐替代
Collections.synchronizedList()遍历时不同步仍会抛异常遍历时加锁或用 CopyOnWriteArrayList
for 循环删除元素ArrayList 删除后索引错位Iterator.remove() 或倒序遍历
多线程用普通集合 + 同步块易遗漏同步导致并发问题直接使用 ConcurrentHashMap

最佳实践:单线程用 Iterator.remove()removeIf(),多线程用并发集合类,Java 8+ 可配合 Stream API 实现无迭代修改。

相关文章:

Java中并发修改异常如何处理

在 Java 中&#xff0c;ConcurrentModificationException&#xff08;并发修改异常&#xff09; 是遍历集合时最常见的错误之一。它发生在迭代过程中直接修改集合结构&#xff08;添加/删除元素&#xff09;时&#xff0c;与是否多线程无关。以下是详细的处理方案&#xff1a; …...

极智项目 | 基于PyQT实现的YOLOv12行人目标检测软件设计

基于YOLOv12的专业级行人目标检测软件应用 开发者: 极智视界 软件下载&#xff1a;链接 &#x1f31f; 项目特色 专业检测: 基于最新YOLOv12模型&#xff0c;专门针对行人检测优化现代界面: 采用PyQt5构建的美观、直观的图形用户界面高性能: 支持GPU加速&#xff0c;检测速…...

JavaScript 对象展开语法

文章目录 JavaScript 对象展开语法1、对象展开&#xff08;Spread&#xff09;操作&#xff1a;2、组件注册3、示例应用总结 JavaScript 对象展开语法 示例代码&#xff1a; export default {...student,components: {ConponentA: ConponentA,ConponentB: ConponentB},这段代…...

简单transformer运用

通俗易懂解读&#xff1a;hw04.py 文件内容与 Transformer 的应用 这个文件是一个 Python 脚本&#xff08;hw04.py&#xff09;&#xff0c;用于完成 NTU 2021 Spring 机器学习课程的 HW4 作业任务&#xff1a;扬声器分类&#xff08;Speaker Classification&#xff09;。它…...

vscode不满足先决条件问题的解决——vscode的老版本安装与禁止更新(附安装包)

目录 起因 vscode更新设置的关闭 安装包 结语 起因 由于主包用的系统是centos的&#xff0c;且版本有点老了&#xff0c;再加上vscode现在不支持老版本的&#xff0c;这对主包来说更是雪上加霜啊 但是主包看了网上很多教程&#xff0c;眼花缭乱&#xff0c;好多配置要改&…...

RustDesk 搭建自建服务器并设置服务自启动

目录 0. 介绍 1. 事前准备 1.1 有公网 ip 的云服务器一台 1.2 服务端部署包 1.3 客户端安装包 2. 部署 2.1 服务器环境准备 2.2 上传服务端部署包 2.3 运行 pm2 3. 客户端使用 3.1 安装 3.2 配置 3.2.1 解锁网络设置 3.2.2 ID / 中级服务器 3.3 启动效果 > …...

【数据库】数据库恢复技术

数据库恢复技术 实现恢复的核心是使用冗余&#xff0c;也就是根据冗余数据重建不正确数据。 事务 事务是一个数据库操作序列&#xff0c;是一个不可分割的工作单位&#xff0c;是恢复和并发的基本单位。 在关系数据库中&#xff0c;一个事务是一条或多条SQL语句&#xff0c…...

Qt企业级串口通信实战:高效稳定的工业级应用开发指南

目录 一、前言 二、问题代码剖析 2.1 典型缺陷示例 2.2 企业级应用必备特性对比 三、关键优化策略与代码实现 3.1 增强型串口管理类 问题1&#xff1a;explicit关键字的作用 3.2 智能错误恢复机制 3.3 数据分帧处理算法 四、性能优化实测数据 五、工业级应用场景 六…...

力扣HOT100之动态规划:32. 最长有效括号

这道题放在动态规划里属实是有点难为人了&#xff0c;感觉用动态规划来做反而更难理解了&#xff0c;这道题用索引栈来做相当好理解&#xff0c;这里先讲下索引栈的思路。 索引栈做法 我们定义一个存放整数的栈&#xff0c;定义一个全局变量result来记录最长有效子串的长度&a…...

深入理解前端DOM:现代Web开发的基石

什么是DOM&#xff1f; DOM&#xff08;Document Object Model&#xff0c;文档对象模型&#xff09;是Web开发中最重要的概念之一。它是一个跨平台、语言独立的接口&#xff0c;将HTML或XML文档表示为树形结构&#xff0c;其中每个节点都是文档的一个部分&#xff08;如元素、…...

Springboot中Controller接收参数的方式

在Spring Boot中&#xff0c;Controller或RestController可以通过多种方式接收客户端传递的参数&#xff0c;主要包括以下几种常见方式&#xff1a; 1. 接收路径参数&#xff08;PathVariable&#xff09; 从URL路径中提取参数&#xff0c;适用于RESTful风格的API。 示例 Re…...

从一堆数字里长出一棵树:中序 + 后序构建二叉树的递归密码

从一堆数字里长出一棵树:中序 + 后序构建二叉树的递归密码 一、写在前面:一棵树的“复活计划” 作为一个老程序员,看到「中序 + 后序重建二叉树」这种题,我内心是兴奋的。为啥?它不仅是数据结构基础的“期末大题”,更是递归分解思想的典范——简洁、优雅、极具思维训练价…...

Unity UI 性能优化终极指南 — Image篇

&#x1f3af; Unity UI 性能优化终极指南 — Image篇 &#x1f9e9; Image 是什么&#xff1f; Image 是UGUI中最常用的基本绘制组件支持显示 Sprite&#xff0c;可以用于背景、按钮图标、装饰等是UI性能瓶颈的头号来源之一&#xff0c;直接影响Draw Call和Overdraw &#x1…...

Nginx + Tomcat 负载均衡、动静分离群集

一、 nginx 简介 Nginx 是一款轻量级的高性能 Web 服务器、反向代理服务器及电子邮件&#xff08;IMAP/POP3&#xff09;代理服务器&#xff0c;在 BSD-like 协议下发行。其特点是占有内存少&#xff0c;并发能力强&#xff0c;在同类型的网页服务器中表现优异&#xff0c;常用…...

【maker-pdf 文档文字识别(包含ocr),安装使用完整教程】

测试效果还比较好&#xff0c;比markitdown要好 安装环境 conda create -n maker-pdf python3.12 conda activate marker-pdf pip install modelscope pip install marker-pdf -U下载模型 建议用modelscope上缓存的模型&#xff0c;不然下载会很慢 from modelscope import s…...

c++ algorithm

cheatsheet&#xff1a;https://hackingcpp.com transform 元素变换 https://blog.csdn.net/qq_44961737/article/details/146011174 #include <iostream> #include <vector> #include <algorithm>int main() {std::vector<int> a {1, 2, 3, 4, 5};…...

《前端面试题:BFC(块级格式化上下文)》

前端BFC完全指南&#xff1a;布局魔法与面试必备 &#x1f38b; 端午安康&#xff01; 各位前端探险家&#xff0c;端午节快乐&#xff01;&#x1f96e; 愿你的代码如龙舟竞渡般乘风破浪&#xff0c;样式如香糯粽子般完美包裹&#xff01;今天我们来解锁CSS中的布局魔法——B…...

HertzBeat的告警规则如何配置?

HertzBeat配置告警规则主要有以下步骤&#xff1a; 配置告警阈值 1. 登录HertzBeat管理界面&#xff0c;点击“阈值规则”菜单&#xff0c;选择“新增阈值”。 2. 选择要配置告警阈值的指标对象。例如&#xff0c;若监控Spring Boot应用&#xff0c;可选择如“状态线程数”等…...

安全-JAVA开发-第一天

目标&#xff1a; 安装环境 了解基础架构 了解代码执行顺序 与数据库进行连接 准备&#xff1a; 安装 下载IDEA并下载tomcat&#xff08;后续出教程&#xff09; 之后新建项目 注意点如下 1.应用程序服务器选择Web开发 2.新建Tomcat的服务器配置文件 并使用 Hello…...

6月2日上午思维训练题解

好好反思一下&#xff0c;自己在学什么&#xff0c;自己怎么在做训练赛的&#xff0c;真有这么难吗 &#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f; A - Need More Arrays 题解 想尽可能多的拆出新数组的个数&#xff0c;只需要从原本的数组中提取出最长的一…...

高考数学易错考点01 | 临阵磨枪

文章目录 前言集合与函数不等式数列三角函数前言 本篇内容下载于网络,网络上的都是以 WORD 版本呈现,缺字缺图很不完整,没法使用,我只是做了补充和完善。有空准备进行第二次完善,添加问题解释的链接。 集合与函数 1.进行集合的交、并、补运算时,不要忘了全集和空集的特…...

【CF】Day69——⭐Codeforces Round 897 (Div. 2) D (图论 | 思维 | DFS | 环)

D. Cyclic Operations 题目&#xff1a; 思路&#xff1a; 非常好的一题 对于这题我们要学会转换和提取条件&#xff0c;从特殊到一般 我们可以考虑特殊情况先&#xff0c;即 k n 和 k 1时&#xff0c;对于 k 1&#xff0c;我们可以显然发现必须满足 b[i] i&#xff0c;而…...

MySQL中的字符串分割函数

MySQL中的字符串分割函数 MySQL本身没有内置的SPLIT()函数&#xff0c;但可以通过其他方式实现字符串分割功能。以下是几种常见的方法&#xff1a; 1. SUBSTRING_INDEX函数 SUBSTRING_INDEX()是MySQL中最常用的字符串分割函数&#xff0c;它可以根据指定的分隔符从字符串中提…...

前端八股之Vue

目录 有使用过vue吗&#xff1f;说说你对vue的理解 你对SPA单页面的理解&#xff0c;它的优缺点分别是什么&#xff1f;如何实现SPA应用呢 一、SPA 是什么 二、SPA 和 MPA 的区别 三、SPA 的优缺点 四、实现 SPA 五、给 SPA 做 SEO 的方式&#xff08;基于 Vue&#xff…...

Matlab数值计算

MATLAB数值计算 数值计算函数句柄匿名函数线性与非线性方程组求解1. \&#xff08;左除运算&#xff09;2. fzero3. fsolve4. roots 函数极值的求解1. fminbnd2. fmincon3. fminsearch与fminunc 数值积分1. quad / quadl2. quadgk3. integral4. trapz5. dblquad, quad2d, integ…...

谷歌地图高清卫星地图2026中文版下载|谷歌地图3D卫星高清版 V7.3.6.9796 最新免费版下载 - 前端工具导航

谷歌地图高清卫星地图2024中文版是一款非常专业的世界地图查看工具。通过使用该软件&#xff0c;你就可以在这里看到外太空星系、大洋峡谷等场景&#xff0c;通过高清的卫星地图&#xff0c;可以清晰查看地图、地形、3D建筑、卫星图像等信息&#xff0c;让你可以更轻松的探索世…...

条形进度条

组件 <template><view class"pk-detail-con"><i class"lightning" :style"{ left: line % }"></i><i class"acimgs" :style"{ left: line % }"></i><view class"progress&quo…...

悟饭游戏厅iOS版疑似流出:未测试版

网传悟饭游戏厅iOS版安装包流出&#xff0c;提供百度网盘/夸克网盘双渠道下载。本文客观呈现资源信息&#xff0c;包含文件验证数据、安装风险预警及iOS正版替代方案。苹果用户请谨慎测试&#xff0c;建议优先考虑官方渠道。 一、资源基本信息 1.1 文件验证数据 属性夸克网盘…...

95. Java 数字和字符串 - 操作字符串的其他方法

文章目录 95. Java 数字和字符串 - 操作字符串的其他方法一、分割字符串二、子序列与修剪三、在字符串中搜索字符和子字符串四、将字符和子字符串替换为字符串五、String 类的实际应用 —— 文件名处理示例示例&#xff1a;Filename 类示例&#xff1a;FilenameDemo 类 总结 95…...

IBM DB2分布式数据库架构

一、什么是分布式数据库架构 分布式数据库架构是现代数据库系统的重要发展方向&#xff0c;特别适合处理大规模数据、高并发访问和高可用性需求的应用场景。下面我们从原理、架构模式、关键技术、实现方式和常见产品几个方面来系统讲 1、分布式数据库的基本概念与原理 1. 什…...