ConcurrentModificationException引发原因源码简析

MYSQL、ORACLE、PostgreSQL数据库对象层次及权限管理对比 本文为出于自己扩展、比较、图形化的思维路径自行总结归纳,可能有些细节不太准确,欢迎指正。MySQL、Oracle、PostgreSQL关系型数据库都有管理员用户、用户、权限管理、表函数索引等数据库对象,schema。但在数据库对象隶属层次上有差异和相同的地方。 阅读详情

Java程序在遍历一个非线程安全的List或Map时,因并发修改很容易出现ConcurrentModificationException,根本原因是遍历时使用的iterator是fail-fast的,也就是说,它认为并发修改是一种不被允许的异常情况,只要出现了就应该尽快失败。

    private class Itr implements Iterator<E> {
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;

        public boolean hasNext() {
            return cursor != size;
        }

        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }

        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

无论是显式地调用iterator()还是通过for-each遍历一个list,都是通过上面的Itr类,它会初始化一个expectedModCount变量,这个变量后面不会变化,除非显式地通过Itr类的remove()方法来移除元素;在next()和remove()方法开始的地方,都会调用checkForComodification()是否有并发修改,当modCount != expectedModCount时就会抛出异常。

modCount是在外围类AbstractList中定义的变量,它记录了这个list被结构性修改(指增加或者删除元素,文中所说的修改都是指结构性修改)的次数。当list增加或者删除元素的时候,都会有modCount++。例如下面的remove()方法(注意这里和上面remove()的区别是:不会改变iterator的expectedModCount):

    public E remove(int index) {
        rangeCheck(index);

        modCount++;
        E oldValue = elementData(index);

        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }

综上所述:

  1. 像ArrayList, LinkedList, HashMap这些非线程安全的容器,在遍历时若有其他线程对容器做了结构性修改,都可能抛出ConcurrentModificationException。
  2. 即使在同一个线程中,在遍历的同时如果调用容器的remove()方法来删除元素,也有可能抛出ConcurrentModificationException,正确的做法是用iterator的remove()来删除。
  3. 设计这个异常的原因是:设计者认为对非线程安全的容器的并发修改是一种非法情况,出现了就应该立即失败。对于需要并发修改的情况,应该使用线程安全的容器。
十五、【测试执行篇】异步与并发:使用 Celery 实现测试任务的后台执行与结果回调 本文介绍如何使用Celery实现测试任务的异步执行与结果回调,解决同步执行测试计划导致的请求阻塞问题。主要内容包括:Celery的基本概念与工作原理(任务队列、消息中间件、Worker进程),在Django项目中集成Celery的步骤,以及将同步测试逻辑改造为异步任务的方法。 阅读详情

相关推荐

【Godot】实现对话系统

在 Godot 中实现对话系统(Dialogue System)是游戏开发中的常见需求。Godot本身自带的的灵活性和轻量级脚本语言 GDScript 使得实现对话系统变得相对简单。以下是实现一个基础对话系统的示例。(语言为GDScript但高亮选择Python因为类似)通过 Godot 和 GDScript,我们可以给我们的游戏实现一个对话系统。从简单的文本显示到复杂的分支对话,Godot 提供了足够的灵活性来满足我们的需求。如果需要更高级的功能,可以尝试使用现成的插件如 Dialogic。

Octopus2077的博客 2522

记录 ConcurrentModificationException异常 解决过程

1、ConcurrentModificationException异常发生原因是一个线程A在对集合做操作的时候,另外一个线程B将集合的内容改变了。导致A线程操作的报ConcurrentModificationException异常 2、知道问题发生的原因就能很快找到解决方案,既然是改变了集合的内容导致的,就找到修改集合内容的代码做处理。 3、思路:如何在A线程对集合操作的时候,让B线程不能修改集合的内容。方法很多不一一列举。 4、我的问题在于我定义了全局变量的集合,在循环前对集合做了排序,然后循环取对

w491797259的博客 3185

【2021最新版】Dubbo面试题总结(40道题含答案解析)

文章目录1、为什么要用Dubbo?2、Dubbo的整体架构设计有哪些分层?3、默认使用的是什么通信框架,还有别的选择吗?4、服务调用是阻塞的吗?5、一般使用什么注册中心?还有别的选择吗?6、默认使用什么序列化框架,你知道的还有哪些?7、服务提供者能实现失效踢出是什么原理?8、服务上线怎么不影响旧版本?9、如何解决服务调用链过长的问题?10、说说核心的配置有哪些?11、Dubbo推荐用什么协议?12、同一个服务多个注册的情况下可以直连某一个服务吗?13、画一画服务注册与发现的流程图?14、Dubbo集群容错有

程序媛小琬的博客 1万+

LinkedList线程安全问题抛出异常java.util.ConcurrentModificationException

1 问题出发场景 定义了一个list LinkedList<Double> avgList = new LinkedList<>(); 在排序的同时,进行了插入的操作 Collections.sort(avgList); avgList.addLast(s); 由于LinkedList是线程不安全的导致抛出异常:ConcurrentModification...

Northwestern的专栏 954

Uni-App推送踩坑实录:从云函数URL化到后台推送失效,我都经历了什么

本文详细记录了Uni-App开发者在接入uni-push 2.0时遇到的推送失效问题,从云函数URL化到后台推送失效的完整排查过程。通过系统化分析和与官方沟通,最终找到解决方案,并分享了预防措施与最佳实践,帮助开发者避免类似问题。

weixin_42552716的博客 487

【HALCON+C#实战】3D点云测量系统开发全攻略:从源码解析到工业应用

本文详细介绍了基于HALCON和C#开发3D点云测量系统的全流程,从环境搭建、核心算法实现到工业应用优化。通过源码解析和实战技巧,帮助开发者解决点云数据处理、几何测量及系统集成中的常见问题,提升工业检测的精度与效率。

brown的博客 210

ConcurrentModificationException异常

ConcurrentModificationException异常一般会在集合迭代过程中被修改时抛出.不仅仅是LinkedHashMap,所有的集合都不允许在迭代器模式中修改集合的结构.一般认为,put()方法,remove()方法会修改集合的结构,因此不能在迭代器中使用. 虽然一般认为get()方法是只读的,但是当前的LinkHashMap如果工作在按照元素顺序排序的模式中,get()方法会修...

欢迎访问,Viola的博客! 1666

OGG工具实现MySQL同步到Oracle数据库

OGG工具实现MySQL同步数据到Oracle

Mrzhou的博客 1682

ConcurrentModificationException并发修改异常产生的原因及解决方案

迭代器

29岁的裴野永远爱你 4304

ardupilot如何让官网支持自己的硬件方案

本节主要记录ardupilot中如何让官网支持自己的硬件方案。参考1参考2。

陌城烟雨 159

SAP_FICO模块-资产减值功能对折旧和残值的影响

SAP_FICO模块-资产减值操作对资产历史折旧以及后续折旧的影响,包括减值操作的配置前提

风沙的博客 2805

ArrayList哪几种情况下会报java.util.ConcurrentModificationException吗?

ArrayList是一个很常用的集合类,底层是一个数组,只不过ArrayList封装了数组,实现了一些好用的方法例如add()方法,size()方法,get()方法等一系列的方法,并且实现了动态的扩容数组。 new ArrayList();创建了一个空数组,那么它的容量起始为0,为什么面试过程中很多人都说ArrayList的初始容量为10呢?原因在于当你第一次调用add()方法添加元素的时候会进行一次扩容。这时候就会扩容到默认的初始容量10 在ArrayList中定义了一个常量DEFAULT_CAPACIT

诗水人间 11万+

MATLAB 图像滤波:高通、低通、带通和方向滤波器

在 MATLAB 中,我们可以使用不同类型的滤波器对图像进行处理,包括高通滤波器、低通滤波器、带通滤波器和方向滤波器。通过以上代码示例,我们介绍了 MATLAB 中使用高通滤波器、低通滤波器、带通滤波器和方向滤波器对图像进行滤波的方法。高斯滤波器可以实现带通滤波效果,通过调整滤波器的方差参数可以控制带通滤波器的频率范围。这里的平均滤波器是一种常见的低通滤波器,通过对图像周围的像素进行平均来实现平滑效果。Sobel 滤波器是一种常用的方向滤波器,用于检测图像中的水平和垂直边缘。函数将高通滤波器应用于图像。

CyberSparkZ的博客 1394

ConcurrentModificationException的产生原因

ConcurrentModificationException的产生原因以及解决办法 1.问题: 在使用ArrayList、Vector、HashMap等集合类的过程中,有时会产生ConcurrentModificationException这个异常,那么这个异常是怎么产生的?如何解决?下面开始分析。 2.原因: 首先,查看JDK源码,看这个异常的作者对这个异常的概要的解释,了解作者...

区生生的博客 3748

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

java.util.ConcurrentModificationException异常原因及解决方法

java.util.ConcurrentModificationException异常原因及解决方法 在java语言中,ArrayList是一个很常用的类,在编程中经常要对ArrayList进行删除操作,在使用remove方法对ArrayList进行删除操作时,报java.util.ConcurrentModificationException异常,下面探讨一下该异常的原因以及解决办法。 import java.util.ArrayList; import java.util.List; public c

java0825的博客 6万+

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Iterator迭代器遍历过程出现ConcurrentModificationException的原因

情况一: 遍历的过程,使用List集合的remove方法删除某个元素,使size的值发生变化,导致 hasNext成立,从而在进行下一步的ite.next()时执行checkForComodification()方法,检查出modCount != expectedModCount成立,最后抛出throw new ConcurrentModificationException()异常。 调试源码核心变量的变化过程如下: 调式源码详细过程如下: 步骤1、首先Debug来到ite.hasNext(); 步骤2

3k油:知道的越多,不知道的越多 1215

Java ConcurrentModificationException异常原因和解决方法

一.ConcurrentModificationException异常出现的原因 从异常信息可以发现,异常出现在checkForComodification()方法中。   我们不忙看checkForComodification()方法的具体实现,我们先根据程序的代码一步一步看ArrayList源码的实现: 首先看ArrayList的iterator()方法的具体实现,查看源码发现在Array...

小强博客 3万+

ConcurrentModificationException异常原因和解决方法

原文地址:https://www.cnblogs.com/dolphin0520/p/3933404.html 一.ConcurrentModificationException异常出现的原因 先看下面这段代码: public class Test { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<Integer>(); lis

weixin_37607613的博客 1万+

ConcurrentModificationException出现原因及解决方式

异常分析 相信写过一些Java代码的人都遇到过这个异常,看下列代码 import java.util.List; import java.util.ArrayList; public class Test{ public static void main(String[] args){ List<String> list = new ArrayList<>(); list.add("123"); list.add("456");

冰蛙 2372

java.util.ConcurrentModificationException异常原因和解决方法

public static List<TreeModel> formatDataStructure(List<House> houseList){ Map<String,Set> checkDuplicates = new HashMap<>(); List<TreeModel> resultTree = new ArrayList<>(); houseList.forEach(hous.

Jason_Dom的博客 3193

Java foreach中List移除元素抛出ConcurrentModificationException原因全解析

一、背景 本文重点探讨 foreach 循环中移除元素造成java.util.ConcurrentModificationException 异常的原因。 先看《阿里巴巴 Java开发手册》中的相关规定: 那么思考几个问题: 反例的运行结果怎样? 造成这种现象的根本原因是什么? 有没有更优雅地的移除元素姿势? 本文将为你深度解读该问题。 二、解读 2.0 反例源代...

悟鸣的技术博客 3375

java.util.ConcurrentModificationException 异常原因和解决方法

前言 二十多天的实训结束了,虽然环境emmmm有点坑,好多人都感冒了,我也没能逃过一劫. 不过总体来说还行, 第一次尝试跟学校里不一样的,7个人一起做项目. 不过也因此对于github的使用不再局限于之前的将其作为云服务备份来使用了,更多的还是大家上传代码,合并冲突之类的,还有也学会了git stash的一些个基础用法,嘻嘻. 这个月还没写点东西记录一下. 这里就记录一下之前遇到过的一个,算...

y4ung 23万+

Java ConcurrentModificationException及fail-fast机制简析

前言 最近还是很忙,写一些相对容易的大家都知道的知识点吧。 ConcurrentModificationException(下文简称CME),即并发修改异常,是Java集合操作中常见的一种异常。本文通过示例及JDK源码分析产生CME的内部机制,并提出解决方法。 CME的产生 java.util包下很多集合的操作都可能会抛出CME,这里就以ArrayList为例。下面的程序产生包含1...

LittleMagic's Blog 683

ConcurrentModificationException异常原因

首先举ConcurrentModificationException的例子: public static void main(String[] args)  {     List list=new ArrayList();     list.add(4);     list.add(5);     list.add(3);     list.add(2);     for(Integ

gol_phing的博客 379
上一篇: 分享:你必须知道的H5加速器九大常识!
下一篇: 《Unity in Action》阅读笔记
长三月
博客等级 码龄9年 228粉丝 80原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值