• 并发修改异常(ConcurrentModificationException)


    并发修改异常(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语句使其相等,所以使用迭代器不会报错

  • 相关阅读:
    ubuntu下查看某个头文件来自哪个软件包?
    系统调用fork()在powerpc上的源码分析
    linux应用程序如何从用户空间进入内核空间?
    执行docker ps时提示"dial unix /var/run/docker.sock: connect: permission denied"如何处理?
    ubuntu上安装远程桌面服务
    执行python安装命令时报错"ModuleNotFoundError: No module named 'setuptools'"如何处理?
    在arm下使用docker build创建容器镜像时磁盘空间不足如何处理?
    9、序列
    8、数据类型
    7、运算符与表达式
  • 原文地址:https://www.cnblogs.com/xtuxiongda/p/9462343.html
Copyright © 2020-2023  润新知