首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

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)条件不成立,抛出异常。 其实质是迭代器设计模式:单线程环境下,如果使用迭代器遍历容器中的元素,必须使用迭代器删除容器中的元素。

35320

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 方法也是一个不错的选择(实际也是上述迭代器写法的封装)。

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

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

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

77620

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

84100

Iterator,fail-fast机制与比较器

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

68820

基于源码去理解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异常,立刻结束迭代器遍历,避免数据不一致。

26701

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

53620

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 } 注意:迭代器只能向后遍历,不能向前遍历,能够删除元素,但是不能新增元素。

1K110

快速失败Vs安全失败(Java迭代器附示例)

Java快速失败与安全失败迭代器 : java迭代器提供了遍历集合对象的功能,集合返回的迭代器有快速失败型的也有安全失败型的,快速失败迭代器在迭代时如果集合类被修改,立即抛出ConcurrentModificationException...java快速失败迭代器 : 大多数集合类返回的快速失败迭代器在遍历时不允许结构性修改(结构性修改指添加,删除和更新一个元素) 当遍历的同时被结构性修改,就会抛出ConcurrentModificationException...快速失败迭代器运行原理: 所有的集合类都维护着一个对象数组(Object[]),用来存储元素, 快速失败迭代器直接从数组中获取元素,在迭代过程中,总是假定该内部数组不会被修改。...迭代器每次调用next()方法,都会检查modCount,如果发现modCount被更新,就会抛出ConcurrentModificationException异常。...ConcurrentModificationException异常 迭代时集合被修改不抛出异常 使用原集合遍历集合元素 使用原集合的副本遍历集合元素 迭代器不要求额外的内存‍‍ ‍‍迭代器需要额外的内存克隆集合对象

1.2K70
领券