ConcurrentModificationException的理解

遍历集合的时候对集合进行了修改,例如添加、删除元素,就会抛这个异常。

产生这个异常的例子:
使用增强for遍历ArrayList,调用list的remove删除元素。

import java.util.ArrayList;
import java.util.List;

public class ConcurrentModificationExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("A");
        list.add("B");
        list.add("C");

        // 使用增强for循环遍历列表
        for (String item : list) {
            if (item.equals("A")) { // remove B不会报错,A,C会报错
                // 尝试在遍历期间移除元素
                list.remove(item); // 将引发ConcurrentModificationException
            }
        }
    }
}

增强for循环底层其实也是用的Iterator

//上述源码编译后的字节码
Iterator var2 = list.iterator();

while(var2.hasNext()) {
    String s = (String)var2.next();
    if (s.equals("a")) {
        list.remove(s);
    }
}

原理:
ArrayList为例。
增强for循环底层其实也是用的Iterator
底层是有个modcount + checkForCmodificatioException()函数,每次调用next的时候,都会调用这个函数,判断一下count是不是预期的值,不是的话就抛异常。
下面ArrayList使用的Iterator源码可以看见。
在这里插入图片描述

在这里插入图片描述

期望的值是在创建迭代器的时候设置的(上面截图第一个红框可以看见),会被设置成modCount,list的remove方法,会将modCount修改(见下图,可以发现这里并没有修改exceptedModCount的值),导致modcount和期望的值不一致,所以list.remove会报错。
在这里插入图片描述

神奇的是,删除第二个元素不报错不信你可以试试,删除B,是不会报错的)。是因为hasNext方法里面是通过cursor != size 去判断是否有下一个元素存在的,删除第二个元素之后,size会减1,等于2,cusor指向的是下一个可用的位置,值也是2,所以hasNext返回false,不会再调用next函数。

Interator为什么调用remove方法的时候,就不报错了?
看第一幅截图,最后remove方法,Interator的remove会将exceptedModCount设置成modCount,这样checkModificationException函数里面这两不就相等了吗?

普通for循环不存在这个异常,因为它不会使用Interator。删除元素可能会导致漏删。

解决方法:
1.使用Interator遍历集合,使用remove方法安全的删除元素
2.使用并发安全的容器。例如ConcurrentHashMap、CopyOnWriteList等
3.SYnchronized或者ReentrantLock显示控制

fail-fast: 程序执行的过程中,出现了错误,就立即停止或者抛异常,而不是继续运行。

参考:
https://juejin.cn/post/7255224807322058810

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

TypeScript和JavaScript的区别

总结&#xff1a; TypeScript 是 JavaScript 的超集&#xff0c;它在 JavaScript 的基础上添加了强类型、接口、类、泛型等特性&#xff0c;并提供了静态类型检查等工具&#xff0c;让开发者能够在编写代码时更加安全、高效、可靠。与 JavaScript 相比&#xff0c;TypeScript …

记录一次网关异常

记一次网关异常 网关时不时就会出现下面的异常。关键是不知道什么时候就会报错&#xff0c;并且有时候就算什么都不操作&#xff0c;也会导致这个异常。 ERROR org.springframework.scheduling.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in schedul…

OpenCV圆形标定板检测算法findCirclesGrid原理详解

OpenCV的findCirclesGrid函数检测圆形标定板的流程如下:   findCirclesGrid函数源码: //_image,输入图像 //patternSize,pattern的宽高 //_centers,blobs中心点的位置 //flags,pattern是否对称 //blobDetector,这里使用的是SimpleBlobDetector bool cv::findCirclesGrid(…

P1226 快速幂

【STUACM-算法入门-快速幂】https://www.bilibili.com/video/BV1Hi4y1L7qB?p2&vd_sourcee583d26dc0028b3e6ea220aadf5bc7fe 想先把a的b次方算出来再对p取模是不可能的&#xff0c;因为肯定超出long long 范围。 需要知道&#xff1a;(x*y)mod p (x mod p)*(y mod p) mo…

Devops-git篇-01-git环境配置

环境配置 设置用户签名 配置用户名&#xff1a; git config --global user.name 你的用户名 配置邮箱&#xff1a; git config --global user.email 注册的邮箱 配置好之后&#xff0c;可以用git config --global --list命令查看配置是否OK $ git config --global --list u…

Create Stunning Word Clouds with Ease!

Looking to craft breathtaking word clouds? WordCloudStudio is your go-to solution! Whether you’re a marketer, educator, designer, or simply someone who loves visualizing data, this app has everything you need. Download now: https://apps.apple.com/app/wor…

Python毕业设计选题:基于Flask的医疗预约与诊断系统

开发语言&#xff1a;Python框架&#xff1a;flaskPython版本&#xff1a;python3.7.7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 系统首页 疾病信息 就诊信息 个人中心 管理员登录界面 管理员功能界面 用户界面 医生…

FPGA实战篇(按键控制LDE实验)

1.按键简介 按键开关是一种电子开关&#xff0c;属于电子元器件类。我们的开发板上有两种按键开关&#xff1a;第一种是本实验所使用的轻触式按键开关&#xff0c;简称轻触开关。使用时以向开关的操作方向施加压力使内部电路闭合接通&#xff0c;当撤销压力时开关断开&#xff…

增加日志定位toast来源

目录 相关问题 案例 分析解决 相关问题 安卓系统集成应用有时会遇到莫名的toast弹框&#xff0c;不清楚是哪个应用&#xff0c;可能频繁弹框影响体验&#xff0c;需要定位来源。 案例 终端未接U盘&#xff0c;却弹出如上toast&#xff0c;需要定位分析来源 分析解决 fram…

曲线积分与曲面积分

1数量函数曲线积分与曲面积分 1.1回顾黎曼积分 回顾之前的定积分是直线积分。 1.1曲线积分的几何意义 1.2曲线积分的性质 1.3中值定理 1.4曲线积分的计算方法 公式里的弧微分&#xff1a;弧微分的几何意义是用一条线段的长度来近似代表一段弧的长度。 图中MT的长度即为弧M…

Java基础面向对象(包装类)

是对八大基本类型做的封装, 使其保留各自的数据特征, 同时变为引用类型, 可以接收存储null值并且也能调用方法 BYTESHORTINTLONGFLOATDOUBLECHARBOOLEANByteShortIntegerLongFloatDoubleCharacterBoolean 基本类型与包装类型 JDK5.0之后, 两者之间可以自动完成封箱与拆箱(自…

2024年12月3日Github流行趋势

项目名称&#xff1a;Lobe Chat 项目维护者&#xff1a;arvinxx, semantic-release-bot, canisminor1990, lobehubbot, renovate项目介绍&#xff1a;一个开源的、现代化设计的人工智能聊天框架。支持多种AI提供商&#xff08;OpenAI / Claude 3 / Gemini / Ollama / Qwen / De…

【AI系统】推理系统引言

引言 在深入探究 AI 编译原理之后&#xff0c;将进一步迈向一个与日常生活紧密相连的新领域。这个领域无处不在&#xff0c;无论是日常使用的购物应用、观看在线视频的平台&#xff0c;还是钟爱的游戏&#xff0c;它们都与这个领域息息相关。该领域&#xff0c;便是推理系统与…

服务器与普通电脑有什么区别?

服务器和普通电脑&#xff08;通常指的是个人计算机&#xff0c;即PC&#xff09;有众多相似之处&#xff0c;主要构成包含&#xff1a;CPU&#xff0c;内存&#xff0c;芯片&#xff0c;I/O总线设备&#xff0c;电源&#xff0c;机箱及操作系统软件等&#xff0c;鉴于使用要求…

计算机网络 —— HTTPS 协议

前一篇文章&#xff1a;计算机网络 —— HTTP 协议&#xff08;详解&#xff09;-CSDN博客 目录 前言 一、HTTPS 协议简介 二、HTTPS 工作过程 1.对称加密 2.非对称加密 3.中间人攻击 4.引入证书 三、HTTPS 常见问题 1.中间人能否篡改证书&#xff1f; 2.中间人能否调…

嵌入式 C 编程:const 关键字 —— 打造稳定的常量空间

目录 一、const关键字的基本含义与用法 1.1. 修饰基本数据类型 1.2. 修饰指针 1.3. 修饰数组 1.4. 修饰结构体 二、const关键字在嵌入式编程中的优势 2.1. 提升代码可读性 2.2. 增强代码安全性 2.3. 优化内存使用 2.4. 促进模块化设计 2.5. 支持静态分析和测试 三、…

信创改造 - Redis -》TongRDS 安装方式之单节点模式安装

安装前准备 安装 JDK 参考链接&#xff1a;安装 JDK 8【Linux】 语雀 创建用户 # 用户名可以自己起 useradd rds 上传安装包到服务器 单节点模式是由两个部署单元组成&#xff1a;1 个RDS 服务节点&#xff0c;1 个 RDS 中心节点。 上传到 /home/rds 用户文件夹&#xff0…

【layui】tabs 控件内通过 iframe 加载url 方式渲染tab页面

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>tabs 内部使用 iframe 嵌套 url 页面</title><link rel"stylesheet" href"../../../libs/layui/layui-2.4.5/dist/css/layui.css"><scr…

Tomcat新手成长之路:安装部署优化全解析(上)

文章目录 1.Tomcat简介2.Tomcat原理架构2.1.总体架构2.2.连接器2.2.1.具体功能2.2.2.IO模型2.2.3.逻辑处理流程2.2.4.内部处理流程 2.3.容器2.4.启动过程2.5.请求过程 3.Tomcat适用场景4.Tomcat与其他Web容器对比5.Tomcat安装和启动5.1.Java环境变量5.2.系统服务5.3.启动关闭 6…

Pycharm 安装两种不同版本的解释器

背景 Pycharm使用的解释器是python3.11&#xff0c;python3.9.x之后不支持win7&#xff1b;有同事需要在win7上使用python制作的exe&#xff0c;而了“win7环境下运行python打包exe提示找不到api-ms-win-core-path-l1-1-0.dll”。 过程 查找了一些资料&#xff0c;发现直接将…