Java ConcurrentModificationExcepton
来源:互联网 发布:黑马程序员全套视频 编辑:程序博客网 时间:2024/06/05 05:26
Java集合遍历中ConcurrentModificationException解决办法
该异常出现的一般原因:不允许的并发修改操作
我们查看Java的API的时候就可以了解到,ConcurrentModificationException是继承了RuntimeException的一个异常,所以它是一个运行时的异常类。通常发生在并发操作’时错误的读写导致的异常错误。这个异常可以通过方法抛出,当探测到对一个对象进行并发修改,然而这个并发修改操作不被允许的时候。
比如说,当一个集合对象是不允许多个线程同时对其进行修改的,当有一个迭代器正在迭代遍历这个集合的时候,如果还有额外的迭代器进行修改操作,这个时候就会报ConcurrentModificationException这个异常。在JDK1.2以及1.2之后就新增了这个异常,至于具体的原因机制可以查看JDK的API文档。点击这里查看1.7版本的JDK。
该异常出现的一般情况:在遍历中对集合中的对象元素进行修改操作
注意:使用迭代器进行遍历,只能通过迭代器进行删除操作,否则则报这个异常,如下:
示例代码1:@Test public void testCreateConcurrentModificationException() { try { ArrayList<String> testList = new ArrayList<String>(); testList.add(new String("One")); testList.add(new String("Two")); testList.add(new String("Three")); Iterator<String> iter1 = testList.iterator(); for (String str = ""; iter1.hasNext();) { str = iter1.next(); testList.remove(0); } } catch (ConcurrentModificationException e) { e.printStackTrace(); } }
此时,绝对爆出异常:
java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(Unknown Source) at java.util.ArrayList$Itr.next(Unknown Source) ...
该异常的原理解析:遍历计数器的不均等导致
如示例代码1所示,这里使用的是testList.remove(0);
,直接使用原集合对象进行删除操作,这样为什么不行呢,原因很简单,我们不妨看一下ArrayList的源码中的方法:
AbstractList 类的 hasNext()和 next()方法:public boolean hasNext() { return cursor != size();} public E next() { checkForComodification(); try { E next = get(cursor); lastRet = cursor++; return next; } catch (IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); }}final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException();}
所以说,在使用迭代器的时候,next()
中调用的checkForComodification()
, 在remove
方法中也调用了checkForComodification()当进行删除操作的时候,modCount ! =expectedModCount
,此时绝对会抛出应有这个异常。总而言之一句话,就是使用那个迭代器时会初始化一个迭代器,使用集合对象本身的add()
或者remove()
操作的时候也会在内部产生一个迭代器,当在迭代器遍历中使用集合对象删除的时候,里边的modCount
会减少,而当使用迭代器的next()
方法时,其检测到的modCount
和期待的count
已经不等了,于是报出这个异常。
该异常的解决方法:在迭代器内部使用迭代器本身进行删除和修改操作
iterator.remove();
延伸:
集合的拷贝:Java集合中深复制与浅复制
笔者本人相关阅读:
在Github上的静态托管博客1:ALBOG
在Github上的静态托管博客2:Programming Sky
在Github上同步博客阅读:ConcurrentModificationException
欢迎大家阅读本人博客,我是Anderson Lu
October 31, 2015 6:59 PM
- Java ConcurrentModificationExcepton
- "Check Android SDK" has encountered a problem. java.util.ConcurrentModificationExcepton
- java
- JAVA
- JAVA
- JAVA
- java
- Java
- Java
- JAVA:
- java
- java
- java
- java
- Java
- java
- java
- java
- HDFS 解析
- jQuery拖放排序插件DDSort
- Android十大常用技术揭秘-挑战
- 关于spring-security登录后重定向至拦截前访问的url的实现原理
- 【HNOI2011】【BZOJ2336】任务调度
- Java ConcurrentModificationExcepton
- Gson的反射解析机制详解(2)
- 符合1-2年工作经验,开发中的难点及相关优化:
- OC内存管理
- 上一个博文开源的漫岛APP做了部分优化
- 学生面试被问到的问题总结
- python的一些问题以及处理思路
- UML图符总结
- 学生面试被问到的问题总结二: