并发修改异常(ConcurrentModificationException)

时间:2023-01-03 15:15:20

并发修改异常(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方法删除元素,就抛出了这种并发修改异常,如下:

并发修改异常(ConcurrentModificationException)

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

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()); } }

并发修改异常(ConcurrentModificationException)

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

我昨天研究过源码之后发现,为什么使用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&lpar;转载&rpar;

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

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

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

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

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

  4. 理解和解决Java并发修改异常&colon;ConcurrentModificationException

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

  5. 并发修改异常ConcurrentModificationException

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

  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. Nancy之基于Nancy&period;Owin的小Demo

    前面做了基于Nancy.Hosting.Aspnet和Nancy.Hosting.Self的小Demo 今天我们来做个基于Nancy.Owin的小Demo 开始之前我们来说说什么是Owin和Katan ...

  2. 证书过期--&gt&semi;app审核提示90034证书错误

    1.证书过期问题,去钥匙串中删除过期证书,然后新下载一个证书,重新添加,注:一定要把所有过期证书全部删除,如果不显示则点击钥匙串-->显示过期证书 然后下载新证书:https://develop ...

  3. 专题:initramfs &amp&semi; dracut

    Initramfs An initramfs (initial ram file system) is used by Linux systems to prepare the system duri ...

  4. 离散化&plus;线段树 POJ 3277 City Horizon

    POJ 3277 City Horizon Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 18466 Accepted: 507 ...

  5. 小白学习mysql之优化基础(EXPLAIN的连接类型)

    ## 导语很多情况下,有很多人用各种select语句查询到了他们想要的数据后,往往便以为工作圆满结束了.这些事情往往发生在一些学生亦或刚入职场但之前又没有很好数据库基础的小白身上,但所谓闻道有先后,只 ...

  6. OS &vert; 读写锁【摘】

    读写锁是用来解决读者写者问题的,读操作可以共享,写操作是排他的,读可以有多个在读,写只有唯一个在写,同时写的时候不允许读. 互斥锁与读写锁的区别: 当访问临界区资源时(访问的含义包括所有的操作:读和写 ...

  7. ttttttttttt

    http://www.2cto.com/kf/201606/519504.html http://a67474506.iteye.com/blog/2079590 spring boot: http: ...

  8. HDU 3555 数位dp

    Bomb Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submi ...

  9. POJ 1674

    #include<iostream>//cheng da cai zi 08 .11 .13 using namespace std; int main() { int digit_num ...

  10. iOS&sol;object-c&colon; 枚举类型 enum&comma;NS&lowbar;ENUM&comma;NS&lowbar;OPTIONS

    一般情况下,我们采用C风格的enum关键字可以定义枚举类型. enum{ UIViewAnimationTransitionNone, UIViewAnimationTransitionFlipFro ...