关于List的ConcurrentModificationException
对ArrayList的操作我们可以通过索引象来访问,也可以通过Iterator来访问,只要不对ArrayList结构上进行修改都不会造成ConcurrentModificationException,单独用索引对ArrayList进行修改也不会造成该问题,造成该问题主要是在索引和Iterator混用。可以通过JDK的源码来说明该问题。
首先看下AbstractList的Iterator内的代码:
- /**
- *在Iterator的内部有个expectedModCount 变量,
- *该变量每次初始化*Iterator的时候等于ArrayList的modCount,modCount记录了对ArrayList的结构修改次数,
- *在通过Iterator对ArrayList进行结构的修改的时候都会将expectedModCount 与modCount同步,
- *但是如果在通过Iterator访问的时候同时又通过索引的方式去修改ArrayList的结构的话,
- *由于通过索引的方式只会修改modCount不会同步修改expectedModCount 就会导致
- *modCount和expectedModCount 不相等就会抛ConcurrentModificationException,
- *这也就是Iterator的fail-fast,快速失效的。所以只要采取一种方式操作ArrayList就不会出问题,
- *当然ArrayList不是线程安全的,此处不讨论对线程问题。
- *
- */
- int expectedModCount = modCount;
- public E next() {
- checkForComodification();//判断modeCount与expectedModCount 是否相等,如果不相等就抛异常
- try {
- E next = get(cursor);
- lastRet = cursor++;
- return next;
- } catch (IndexOutOfBoundsException e) {
- checkForComodification();
- throw new NoSuchElementException();
- }
- }
- public void remove() {
- if (lastRet == -1)
- throw new IllegalStateException();
- checkForComodification();//同样去判断modeCount与expectedModCount 是否相等
- try {
- AbstractList.this.remove(lastRet);
- if (lastRet < cursor)
- cursor--;
- lastRet = -1;
- expectedModCount = modCount;//此处修改ArrayList的结构,所以要将expectedModCount 于modCount同步,主要是AbstractList.this.remove(lastRet);的remove方法中将modCount++了,导致了modCount与expectedModCount 不相等了。
- } catch (IndexOutOfBoundsException e) {
- throw new ConcurrentModificationException();
- }
- }
- //判断modCount 与expectedModCount是否相等,如果不相等就抛ConcurrentModificationException异常
- final void checkForComodification() {
- if (modCount != expectedModCount)
- throw new ConcurrentModificationException();
- }
故我的结论是:对ArrayList的操作采用一种遍历方式,要么索引,要么Iterator别混用即可。
下面是网上看见别人的解释:写道
所以 Iterator 在工作的时候是不允许被迭代的对象被改变的。但你可以使用 Iterator 本身的方法 remove() 来删除对象, Iterator.remove() 方法会在删除当前迭代对象的同时维护索引的一致性
关于List的ConcurrentModificationException的更多相关文章
- java.util.ConcurrentModificationException 解决办法(转载)
今天在项目的中有一个需求,需要在一个Set类型的集合中删除满足条件的对象,这时想当然地想到直接调用Set的remove(Object o)方法将指定的对象删除即可,测试代码: public cla ...
- java.util.ConcurrentModificationException异常处理
ConcurrentModificationException异常处理 ConcurrentModificationException异常是Iterator遍历ArrayList或者HashMap数组 ...
- java.util.ConcurrentModificationException --map
key:3-key key:/v1.02-key Exception in thread "main" java.util.ConcurrentModificationExcept ...
- 偶遇到 java.util.ConcurrentModificationException 的异常
今天在调试程序 遇到了如此问题 贴上代码来看看稍后分析 List<String> list = null;boolean isUpdate = false;try { list = JSO ...
- 集合框架之——迭代器并发修改异常ConcurrentModificationException
问题: 我有一个集合,如下,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现. 使用普通迭代器出现的异常: ...
- 对ArrayList操作时报错java.util.ConcurrentModificationException null
用iterator遍历集合时要注意的地方:不可以对iterator相关的地方做添加或删除操作.否则会报java.util.ConcurrentModificationException 例如如下代码: ...
- Java ConcurrentModificationException异常原因和解决方法
Java ConcurrentModificationException异常原因和解决方法 在前面一篇文章中提到,对Vector.ArrayList在迭代的时候如果同时对其进行修改就会抛出java.u ...
- LinkedList - java.util.ConcurrentModificationException
package com.test.io; import java.io.BufferedReader; import java.io.FileNotFoundException; import jav ...
- java 多线程操作List,已经做了同步synchronized,还会有ConcurrentModificationException,知道为什么吗?
如题,最近项目里有个模块我做了异步处理方面的事情,在code过程中发现一个颠覆我对synchronized这个关键字和用法的地方,请问各位java开发者们是否对此有一个合理的解释,不多说,我直接贴出问 ...
随机推荐
- Maven创建web项目:SpringMVC+Mybatis 【转】
IDEA14创建Maven管理的SpringMVC+Mybatis,web项目 项目构建步骤 1.File->New->Project 勾选Create from archetype 点击 ...
- 利用H5和ChromiumWebBrowser构建应用
chromium是google chrome浏览器所采用的内核,最开始由苹果的webkit发展而出,由于webkit在发展上存在分歧,而google希望在开发上有更大的自由度,2013年google决 ...
- AndroidStudio安装流程 以及 使用过程中出现的异常
Android Studio2.0 教程从入门到精通Windows版 - 安装篇 Android Studio第一次启动跳不过“ downloading components”解决方案 通过hosts ...
- Android面试题(一)
1. 请描述一下Activity 生命周期. 答: 如下图所示.共有七个周期函数,按顺序分别是: onCreate(), onStart(), onRestart(), onResume(), onP ...
- django 第三天 有关pip使用
软件应用开发的经典模型有这样几个环境:开发环境(development).集成环境(integration).测试环境(testing).QA验证,模拟环境(staging).生产环境(product ...
- UINavigationBar 和view 重叠覆盖问题
如果没有是storyboard进行界面设计,在ios7之后会遇到rootviewcontroller的view被navigationbar遮盖的问题,其实很好解决 - (void)viewDidLoa ...
- 3、项目资源的提供 - PMO项目管理办公室
PMO项目管理办公室也需要对项目相关的资源进行提供,从而针对项目的资源也进行标准化和规范化的管理.也就是说,PMO项目管理办公室就是提供项目相关的规范化资源内容,从而统一管理项目相关的内容,达到规范的 ...
- python处理json和redis hash的坑
1.使用MySQLdb读取出来的数据是unicode字符串,如果要写入redis的hash中会变成 "{u'eth0_outFlow': 2.5, u'eth1_inFlow': 3.44} ...
- 生产环境常见的HTTP状态码列表
生产环境常见的HTTP状态码列表(List of HTTP status codes)为: 200 - OK,服务器成功返回网页 - Standard response for success ...
- RHEL6和RHEL7恢复root用户密码
一.RHEL6恢复root密码 将系统重启,出现如下界面按上下键选择会停住,并输入e键 选中下图红框选项,再输入e键 再输入1,进入单用户模式 输入b进行启动 修改密码,然后重启 二.RHEL7恢 ...