并发修改异常(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. 【转】AngularJs HTTP请求响应拦截器

    任何时候,如果我们想要为请求添加全局功能,例如身份认证.错误处理等,在请求发送给服务器之前或服务器返回时对其进行拦截,是比较好的实现手段. angularJs通过拦截器提供了一个从全局层面进行处理的途 ...

  2. CentOS 7 - 配置服务实现开机自启动

    新建系统服务描述文件 cd /etc/systemd/system sudo vim myapp.service 添加以下配置: [Unit] # 这里添加你的服务描述 Description=mya ...

  3. 100道Java基础面试题

    1.什么是B/S架构?什么是C/S架构 B/S(Browser/Server),浏览器/服务器程序 C/S(Client/Server),客户端/服务端,桌面应用程序 2.你所知道网络协议有那些? H ...

  4. Nginx安装使用及与tomcat实现负载均衡

    1. 背景 基于nginx强大的功能,实现一种负载均衡,或是不停机更新程序等.nginx相比大家基本上都知道是什么来头了,具体的文章大家可以去搜索相关文章学习阅读,或是可以查看Nginx中文文档和Ng ...

  5. ASP.NETCore学习记录(二) —— ASP.NET Core 中间件

    ASP.NET Core 中间件 目录: 什么是中间件 ? IApplicationBuilder 使用 IApplicationBuilder 创建中间件 Run.Map 与 Use 方法 实战中间 ...

  6. 关于使用 IDEA Spring Boot 热部署

    1,POM 中引用 <dependency> <groupId>org.springframework.boot</groupId> <artifactId& ...

  7. Python -----issubclass和isinstance

    issubclass用于判断一个类是否为另一个类的子类,isinstance用于判断一个对象是否某类的一个实例 import math class Point: def __init__(self, ...

  8. 使用Docker发布应用

    新建spring boot应用demo-docker,添加web依赖 <dependency> <groupId>org.springframework.boot</gr ...

  9. CodeSmith读取数据库

    这两天在看CodeSmith文档,因为官方文档在读数据库这一篇使用的是VB写的,对于C#使用者来说看起来很不方便,所以我改成C#的,顺便写下我自己的使用过程. 首先,要使用CodeSmith连接数据库 ...

  10. Android_ 重写系统Crash处理类,保存Crash信息到SD卡 和 完美退出程序的方法

    转载时注明地址:http://blog.csdn.net/xiaanming/article/details/9344703 我们开发Android应用的时候,当出现Crash的时候,系统弹出一个警告 ...