首页
学习
活动
专区
圈层
工具
发布

java陷阱之:HashMap for each遍历同时删除,抛出ConcurrentModificationException

---- 现象 ---- 当HashMap使用for each遍历entrySet的同时,使用HashMap的remove操作元素时,并不是在并发的情况下,也会抛出异常:ConcurrentModificationException...map.remove("a"); } } } 运行结果: Exception in thread "main" java.util.ConcurrentModificationException...= expectedModCount) throw new ConcurrentModificationException(); if (e ==...for-each循环遍历不会更改Iterator实例中expectedModCount值,而HashMap中的modCount值,当使用java.util.HashMap#remove(java.lang.Object...= expectedModCount)条件不成立,抛出异常。 其实质是迭代器设计模式:单线程环境下,如果使用迭代器遍历容器中的元素,必须使用迭代器删除容器中的元素。

84120

Java|如何正确地在遍历 List 时删除元素

最近在一个 Android 项目里遇到一个偶现的 java.util.ConcurrentModificationException 异常导致的崩溃,经过排查,导致异常的代码大概是这样的: private...源码分析 先来从源码层面分析下上述 java.util.ConcurrentModificationException 异常是如何抛出的。..."); for (String str : list) { list.remove(str); } 执行抛出异常: Exception in thread "main" java.util.ConcurrentModificationException...如果需要在遍历 List 时删除元素,应使用迭代器的写法,即 iterator.remove(); 在非遍历场景下,使用 ArrayList#remove 也没什么问题——同理,即使是遍历场景下,使用...ArrayList#remove 后马上 break 也 OK; 如果遍历时做的事情不多,Collection#removeIf 方法也是一个不错的选择(实际也是上述迭代器写法的封装)。

1.5K10
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    Java集合详解3:一文读懂Iterator,fail-fast机制与比较器

    快速失败迭代器会尽最大努力抛出ConcurrentModificationException。...快速失败迭代器尽最大努力抛出 ConcurrentModificationException。因此,编写依赖于此异常的程序的做法是错误的,正确做法是:迭代器的快速失败行为应该仅用于检测程序错误。...例如:假设存在两个线程(线程1、线程2),线程1通过Iterator在遍历集合A中的元素,在某个时候线程2修改了集合A的结构(是结构上面的修改,而不是简单的修改集合元素的内容),那么这个时候程序就会抛出...要了解fail-fast机制,我们首先要对ConcurrentModificationException 异常有所了解。当方法检测到对象的并发修改,但不允许这种修改时就抛出该异常。...线程A继续遍历执行next方法时,通告checkForComodification方法发现expectedModCount = N ,而modCount = N + 1,两者不等,这时就抛出ConcurrentModificationException

    1.2K00

    Java - Java集合中的快速失败Fail Fast 机制

    在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的结构进行了修改(增加、删除),则会抛出Concurrent Modification Exception 【并发修改异常】。...举个例子: 在多线程环境下,线程1正在对集合进行遍历,此时线程2对集合进行修改(增加、删除、修改), 很容易抛出Concurrent Modification Exception 。...当然了,在单线程的情况下,遍历时对集合进行修改(增加、删除、修改)也会抛出Concurrent Modification Exception 此类的返回的迭代器iterator和 listIterator...= expectedModCount的时候抛出了ConcurrentModificationException, 而在next方法中上来就是调用checkForComodification,所以遍历集合才会可能抛出并发修改异常...modCount 是ArrayList的常量,默认值 为0 ---- 为什么对集合的结构进行修改会发生并发修改异常-源码分析 那我们说,在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的结构进行了修改

    1.2K20

    Iterator,fail-fast机制与比较器

    快速失败迭代器会尽最大努力抛出ConcurrentModificationException。...快速失败迭代器尽最大努力抛出 ConcurrentModificationException。因此,编写依赖于此异常的程序的做法是错误的,正确做法是:迭代器的快速失败行为应该仅用于检测程序错误。...要了解fail-fast机制,我们首先要对ConcurrentModificationException 异常有所了解。当方法检测到对象的并发修改,但不允许这种修改时就抛出该异常。...若不等则抛出ConcurrentModificationException 异常,从而产生fail-fast机制。...线程A继续遍历执行next方法时,通告checkForComodification方法发现expectedModCount = N ,而modCount = N + 1,两者不等,这时就抛出ConcurrentModificationException

    91220

    基于源码去理解Iterator迭代器的Fail-Fast与Fail-Safe机制

    先简单介绍下这两种策略——Fail-Fast(快速失败)机制快速失败机制是指集合在迭代遍历过程中,其他多线程或者当前线程对该集合进行增加或者删除元素等操作,当前线程迭代器读取集合时会立马抛出一个ConcurrentModificationException...Fail-Safe(安全失败)机制安全失败机制是指集合在迭代遍历过程中,若其他多线程或者当前线程对该集合进行修改(增加、删除等元素)操作,当前线程迭代器仍然可以正常继续读取集合遍历,而不会抛出异常。..." java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java...*如果该字段的值发生了意外变化,迭代器(或列表)将返回该字段迭代器)将抛出{@code ConcurrentModificationException} *在响应{@code next}, {@code...是否还等于modCount,这时已经不等于,故而就会抛出ConcurrentModificationException异常,立刻结束迭代器遍历,避免数据不一致。

    66801

    Java集合详解3:一文读懂Iterator,fail-fast机制与比较器

    快速失败迭代器会尽最大努力抛出ConcurrentModificationException。...快速失败迭代器尽最大努力抛出 ConcurrentModificationException。因此,编写依赖于此异常的程序的做法是错误的,正确做法是:迭代器的快速失败行为应该仅用于检测程序错误。...例如:假设存在两个线程(线程1、线程2),线程1通过Iterator在遍历集合A中的元素,在某个时候线程2修改了集合A的结构(是结构上面的修改,而不是简单的修改集合元素的内容),那么这个时候程序就会抛出...要了解fail-fast机制,我们首先要对ConcurrentModificationException 异常有所了解。当方法检测到对象的并发修改,但不允许这种修改时就抛出该异常。...线程A继续遍历执行next方法时,通告checkForComodification方法发现expectedModCount = N ,而modCount = N + 1,两者不等,这时就抛出ConcurrentModificationException

    67520

    深入Java集合框架:解密List的Fail-Fast与Fail-Safe机制

    当我们遍历并修改集合时,并不会抛出 ConcurrentModificationException 异常,这是由于 CopyOnWriteArrayList 在写操作时使用了副本机制来保证线程安全和 Fail-Safe...在这段代码中,我们使用了 ArrayList 集合,并在遍历时对集合进行了修改。...这会导致并发修改异常 (ConcurrentModificationException) 的发生,这是因为 ArrayList 是 Fail-Fast 的,在遍历时检测到结构被修改时会立刻抛出异常。...如果在遍历过程中检测到集合的结构发生了变化(比如 remove 操作),就会抛出 ConcurrentModificationException 异常,以防止数据不一致性。...modCount 机制:ArrayList 中维护了一个 modCount 变量,每次结构发生修改时都会更新 modCount,迭代器在遍历时会检查这个值是否发生变化,从而决定是否抛出异常。

    42131

    JDK1.8源码(五)——java.util.ArrayList 类

    的迭代器使用的,在并发操作被修改时,提供快速失败行为(保证modCount在迭代期间不变,否则抛出ConcurrentModificationException异常,可以查看源码865行),接着判断minCapacity...8、遍历集合   ①、普通 for 循环遍历   前面我们介绍查找元素时,知道可以通过get(int index)方法,根据索引查找元素,那么遍历同理: 1 ArrayList list = new ArrayList...}   注意在进行 next() 方法调用的时候,会进行 checkForComodification() 调用,该方法表示迭代器进行元素迭代时,如果同时进行增加和删除操作,会抛出 ConcurrentModificationException...,都会抛出 ConcurrentModificationException 异常 10 //list.add(str); 11 list.set(0, str);//修改操作不会造成异常...,都会抛出 ConcurrentModificationException 异常 6 it.remove(); 7 } 注意:迭代器只能向后遍历,不能向前遍历,能够删除元素,但是不能新增元素。

    1.3K110
    领券