并发修改异常(ConcurrentModificationException)

这个异常,使用集合的时候应该很常见,这个异常产生的原因是因为java中不允许直接修改集合的结构。

先贴上个有趣的例子,给你们看看:

package com.xiongda;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; public class Confirm { public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("4");
list.add("3");
list.add("6");
Iterator<String> iterator = list.iterator(); while(iterator.hasNext()){
String integer = iterator.next();
if(integer.equals("2")) {
list.remove("2");
} } System.out.println(list.toString()); } }

我们使用list的remove方法删除元素,就抛出了这种并发修改异常,如下:

但是,我们改为判断倒数第二个数,删除任意元素,就不报错了:

package com.xiongda;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; public class Confirm { public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("4");
list.add("3");
list.add("6");
Iterator<String> iterator = list.iterator(); while(iterator.hasNext()){
String integer = iterator.next();
if(integer.equals("3")) {
list.remove("2");
} } System.out.println(list.toString()); } }

这是为什么?是不是很神奇?

我昨天研究过源码之后发现,为什么使用arraylist的remove方法会抛出这个异常呢,因为arraylist中的add和remove方法都造成了modcount 和 exceptmodcpiunt不等。

而异常中抛出异常的那个方法checkformodification方法就是检查这两个值知否相等。

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

那么为什么,但判断走到了倒数第二个元素,删除就没有抛出异常了呢?

仔细看抛出的异常,是next方法里面调用的checkformodification方法:

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];
}

当判断到倒数第二个的时候,remove掉了一个,此时的index和size相等了,就不执行循环了,就不执行next方法了,所以异常就没有抛出来了

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

那么为什么使用迭代器的remove方法不会报错,而使用arraylist的remove方法会报错呢?

这是因为list中的remove方法会使modcount++,但是迭代器中remove方法中多了一条modcount = exceptmodcount语句使其相等,所以使用迭代器不会报错

并发修改异常(ConcurrentModificationException)的更多相关文章

  1. 理解和解决Java并发修改异常ConcurrentModificationException(转载)

    原文地址:https://www.jianshu.com/p/f3f6b12330c1 理解和解决Java并发修改异常ConcurrentModificationException 不知读者在Java ...

  2. 集合框架之——迭代器并发修改异常ConcurrentModificationException

    问题: 我有一个集合,如下,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现. 使用普通迭代器出现的异常: ...

  3. 大杂烩 -- Iterator 并发修改异常ConcurrentModificationException

    基础大杂烩 -- 目录 大杂烩 -- Java中Iterator的fast-fail分析 大杂烩 -- Iterator 和 Iterable 区别和联系 问题: 在集合中,判断里面有没有" ...

  4. 理解和解决Java并发修改异常:ConcurrentModificationException

    參考文獻:https://www.jianshu.com/p/f3f6b12330c1 文獻来源:简书 关键字: Java Exception遇到异常信息Exception in thread &qu ...

  5. 并发修改异常ConcurrentModificationException

    1.简述:在使用 迭代器对象遍历集合时,使用集合对象修改集合中的元素导致出现异常 public static void main(String[] args) { List<Integer> ...

  6. ConcurrentModificationException(并发修改异常)的解决

    [异常解释] ConcurrentModificationException:当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常.[产生的原因] 迭代器是依赖于集合而存在的,在判断成功后,集合 ...

  7. ConcurrentModificationException 集合并发修改异常 解决

    import java.util.ArrayList; import java.util.List; import java.util.ListIterator; /** * 问题? * 有一个集合, ...

  8. java 15 - 8 集合框架(并发修改异常的产生原因以及解决方案)

    问题?   我有一个集合,如下,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现.  面试题: Concu ...

  9. Java基础知识强化之集合框架笔记19:List集合迭代器使用之 并发修改异常的产生原因 以及 解决方案

    1. 我有一个集合,如下,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现. ConcurrentModi ...

随机推荐

  1. ConcurrentHashMap源码解析(2)

    此文已由作者赵计刚授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. ConcurrentHashMap()     /**      * 创建ConcurrentHashMap ...

  2. sudo: 没有终端存在,且未指定 askpass 程序

    问题:sudo: 没有终端存在,且未指定 askpass 程序 解决: sudo visudo 增加如下一行: neutron    ALL=(ALL)    NOPASSWD:ALL

  3. JQuery - on绑定多个事件

    一.jquery为多个选择器绑定同一个事件 $("#start,#end").on("click",function(){ alert("The pa ...

  4. Python 基础之class魔术方法

    类的常用魔术方法:无需人为调用,基本是在特定的时刻自动触发,方法名被前后两个下划线包裹 魔术方法,总结表: __init__:构造函数.初始化的时候调用. __new__:对象实例化方法,其实这才是类 ...

  5. Swift5 语言参考(三) 类型

    在Swift中,有两种类型:命名类型和复合类型.一个名为类型是当它的定义可以给出一个特定名称的类型.命名类型包括类,结构,枚举和协议.例如,名为的用户定义类的实例MyClass具有该类型MyClass ...

  6. 重识 PWA 进阶到 workbox3

    看到PWA,似曾相识,但又感觉很模糊,于是乎,又重新翻阅文档,学习了一遍,顺便把相关知识学习了一下,比如service worker,workbox3. PWA 概念: 全称:Progressive ...

  7. Selenium3 + Python3自动化测试系列四——鼠标事件和键盘事件

    一.鼠标事件 在 WebDriver 中, 将这些关于鼠标操作的方法封装在 ActionChains 类提供. ActionChains 类提供了鼠标操作的常用方法. ActionChains 类的成 ...

  8. odoo开发环境搭建(三):安装odoo依赖的python包

    odoo开发环境搭建(三):安装odoo依赖的python包 http://www.cnblogs.com/jlzhou/p/5940815.html

  9. 刚破了潘金莲的身份信息(图片文字识别),win7、win10实测可用(免费下载)

    刚破了潘金莲的身份信息(图片文字识别),win7.win10实测可用 效果如下: 证照,车牌.身份证.名片.营业执照 等图片文字均可识别 电脑版 本人出品 大小1.3MB 下载地址:https://p ...

  10. CentOs 7 安装Spark

    环境 centos7 hadoop 2.7.3 java 1.8 下载 http://spark.apache.org 解压到安装目录 可以自由选择,我安装到hadoop同一目录 配置 (cd spa ...