精华内容
下载资源
问答
  • 并发修改异常

    2019-06-21 16:13:29
    ConcurrentModificationException: 并发修改异常:使用迭代器遍历集合的时候修改了集合的长度

    ConcurrentModificationException:
    并发修改异常:使用迭代器遍历集合的时候修改了集合的长度

    解决方法:不用迭代器 ,使用普通for循环

    展开全文
  • 在多线程编程中,相信很多小伙伴都遇到过并发修改异常ConcurrentModificationException,本篇文章我们就来讲解并发修改异常的现象以及分析一下它是如何产生的。 异常产生原因:并发修改异常指的是在并发环境下,当...

    目录

    一、简介

    二、异常原因分析

    三、异常原因追踪

    四、如何避免并发修改异常?

    五、总结

    一、简介

    在多线程编程中,相信很多小伙伴都遇到过并发修改异常ConcurrentModificationException,本篇文章我们就来讲解并发修改异常的现象以及分析一下它是如何产生的。

    • 异常产生原因:并发修改异常指的是在并发环境下,当方法检测到对象的并发修改,但不允许这种修改时,抛出该异常。

    下面看一个示例:

    public class TestConcurrentModifyException {
        public static void main(String[] args) {
            List<String> list = new ArrayList<>();
            list.add("1");
            list.add("2");
            list.add("3");
            Iterator<String> iterator = list.iterator();
            while (iterator.hasNext()) {
                String nextElement = iterator.next();
                if (Integer.parseInt(nextElement) < 2) {
                    list.add("2");
                }
            }
        }
    }

    运行此程序,控制台输出,程序出现异常:

    Exception in thread "main" java.util.ConcurrentModificationException
    	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
    	at java.util.ArrayList$Itr.next(ArrayList.java:851)
    	at com.wsh.springboot.helloworld.TestConcurrentModifyException.main(TestConcurrentModifyException.java:15)

    可见,控制台显示的ConcurrentModificationException,即并发修改异常。下面我们就以ArrayList集合中出现的并发修改异常为例来分析异常产生的原因。

    二、异常原因分析

    通过上面的异常信息可见异常抛出在ArrayList类中的checkForComodification()方法中。下面是checkForComodification方法的源码: 

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

    checkForComodification()方法实际上就是当modCount 变量值不等于expectedModCount变量值时,就会触发此异常。

    那么modCount 和expectedModCount分别代表什么呢?

    • modCount :AbstractList类中的一个成员变量,由于ArrayList继承自AbstractList,所以ArrayList中的modCount变量也继承过来了。
    protected transient int modCount = 0;

    简单理解,modCount 就是ArrayList中集合结构的修改次数【实际修改次数】,指的是新增、删除(不包括修改)操作

    • expectedModCount:是ArrayList中内部类Itr的一个成员变量,当我们调用iteroter()获取迭代器方法时,会创建内部类Itr的对象,并给其成员变量expectedModCount赋值为ArrayList对象成员变量的值modCount【预期修改次数】。 
    private class Itr implements Iterator<E> {
        //游标, 每获取一次元素,游标会向后移动一位
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        //将ArrayList对象成员变量的值modCount赋值给expectedModCount成员变量
        int expectedModCount = modCount;
        //....
        }

    经过上面的分析,我们知道了当我们获取到集合的迭代器之后,Itr对象创建成功后,expectedModCount 的值就确定了,就是modCount的值,在迭代期间不允许改变了。要了解它两为啥不相等, 我们就需要观察ArrayList集合的什么操作会导致modCount变量发生变化,从而导致modCount != expectedModCount ,从而发生并发修改异常。

    查看ArrayList的源码可知,modCount 初始值为0, 每当集合中添加一个元素或者删除一个元素时,modCount变量的值都会加一,表示集合中结构修改次数多了一次。下面简单看下ArrayList的add()方法和remove()方法。

    • add():每添加一个元素,modCount的值也会自增一次
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
    
    private void ensureCapacityInternal(int minCapacity) {
        //第一次添加元素
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            //默认容量DEFAULT_CAPACITY为10
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }
    
        ensureExplicitCapacity(minCapacity);
    }
    
    private void ensureExplicitCapacity(int minCapacity) {
        //集合结构修改次数加一
        modCount++;
    
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            //扩容方法,扩容后是原容量的1.5倍
            //扩容前:数组长度10  扩容后:数组长度变为10 + (10 / 2) = 15
            grow(minCapacity);
    }
    • remove():每删除一个元素,modCount的值会自增一次
    public E remove(int index) {
        //检查索引是否越界
        rangeCheck(index);
        
        //集合结构修改次数加一
        modCount++;
        //数组中对应索引的值
        E oldValue = elementData(index);
    
        //计算需要移动元素的位数
        int numMoved = size - index - 1;
        if (numMoved > 0)
            //数组拷贝
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        //将元素置空,利于垃圾回收
        elementData[--size] = null; // clear to let GC do its work
        //返回原先索引对应的值
        return oldValue;
    }

    注意!注意!注意!ArrayList中的修改方法set()并不会导致modCount变量发生变化,set()方法源码如下:

    public E set(int index, E element) {
        rangeCheck(index);
    
        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }

    三、异常原因追踪

     下面我们就Debug调试一下刚刚那个例子,详解了解一下,并发修改异常时怎么产生的。

    当我们调用iterator()获取迭代器时,实际上底层创建了一个Itr内部类对象

    public Iterator<E> iterator() {
        return new Itr();
    }

    初始化Itr的成员变量:可以看到,expectedModCount = 3,表示预期修改次数为3,如果在迭代过程中,发现modCount不等于3了,那么就会触发并发修改异常。

    下面简单说明一下Itr的源码:

    private class Itr implements Iterator<E> {
        //cursor初始值为0,每次取出一个元素,cursor值会+1,以便下一次能指向下一个元素,直到cursor值等于集合的长度为止
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        //初始化预期修改次数为实际修改次数modCount,即上图中的3
        int expectedModCount = modCount;
    
        //判断是否还有下一个元素:通过比较游标cursor是否等于数组的长度
        //因为集合中最后一个元素的索引为size-1,只要cursor值不等于size,证明还有下一个元素,此时hasNext方法返回true,
       //如果cursor值与size相等,那么证明已经迭代到最后一个元素,返回false
        public boolean hasNext() {
            return cursor != size;
        }
    
        //拿出集合中的下一个元素
        @SuppressWarnings("unchecked")
        public E next() {
            //并发修改异常出现根源
            //ConcurrentModificationException异常就是从这抛出的
            //当迭代器通过next()方法返回元素之前都会检查集合中的modCount和最初赋值给迭代器的expectedModCount是否相等,如果不等,则抛出并发修改异常
            checkForComodification();
            int i = cursor;
            //判断,如果大于集合的长度,说明没有元素了。
            if (i >= size)
                throw new NoSuchElementException();
            //将集合存储数据数组的地址赋值给局部变量elementData     
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            //每次获取完下一个元素后,游标向后移动一位    
            cursor = i + 1;
            //返回当前游标对应的元素
            return (E) elementData[lastRet = i];
        }
    
        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();
    
            try {
                ArrayList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }
        
        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

    继续Debug,我们记录一下几次hasNext()/next()方法时,其中几个重要变量值的变化过程。

    第一次调用hasNext(): cursor = 0    size = 3
    第一次调用iterator.next():
        第一次调用checkForComodification():modCount = 3  expectedModCount = 3
    由于 modCount = expectedModCount ,不会发生并发修改异常。并且返回当前游标对应的值,即返回1.
    由于满足Integer.parseInt(nextElement) < 2,所以会执行list.add("2")方法,之前已经了解到,add()方法会
    修改modCount的值 + 1· 所以此时modCount的值变为4了.
    第一次next()方法调用完,cursor游标的值会加一,所以cursor = 1. 
    
    ===============================================================================================================
    第二次调用hasNext(): cursor = 1  size = 4
    第二次调用iterator.next():
        第二次调用checkForComodification():modCount = 4  expectedModCount = 3
    由于 modCount != expectedModCount ,此时会发生并发修改异常。
    
    以上就是ConcurrentModificationException一场产生的简单解析过程。  

    下图是发生并发修改异常时checkForComodification()方法的执行过程,注意modCount和expectedModCount 的值:

    四、并发修改异常的特殊情况

    示例:已知集合中有三个元素:"chinese"、"math"、"english",使用迭代器进行遍历, 判断集合中存在"english",如果存在则删除。

    public class TestConcurrentModifyException {
        public static void main(String[] args) {
            List<String> list = new ArrayList<>();
            list.add("chinese");
            list.add("math");
            list.add("english");
            Iterator<String> iterator = list.iterator();
            while (iterator.hasNext()) {
                String nextElement = iterator.next();
                if ("english".equals(nextElement)) {
                    //使用ArrayList的boolean remove(Object o)方法进行删除
                    list.remove("english");
                }
            }
        }
    }

    程序运行结果:

    Exception in thread "main" java.util.ConcurrentModificationException
    	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
    	at java.util.ArrayList$Itr.next(ArrayList.java:851)
    	at com.wsh.springboot.helloworld.TestConcurrentModifyException.main(TestConcurrentModifyException.java:19)

    通过上面的分析,由于往集合中加入了三个元素,所以modCount实际修改次数的值为3,当我们调用iterator()获取迭代器的时候,初始化expectedModCount的值也为3。下面我们一起看一下ArrayList类中的根据元素删除方法的源码。

    remove(Object o)方法源码: 

    public boolean remove(Object o) {
        //判断需要删除的元素是否为null
        if (o == null) {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            //不为null,遍历集合,使用equals进行比较是否相等
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }
    
    private void fastRemove(int index) {
        //删除元素时,实际修改次数会自增1
        //此时: modCount实际修改次数为4,但是预期修改次数还是获取迭代器时候的3,两者已经不一致了。
        modCount++;
        //计算集合需要移动元素的个数
        int numMoved = size - index - 1;
        if (numMoved > 0)
            //数组拷贝
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        //将删除元素置为null,利于垃圾回收
        elementData[--size] = null; // clear to let GC do its work
    }

    我们分析一下程序的执行过程,查看并发修改异常是怎么产生的。当我们执行到下面一行语句之后,集合的size会减1,所以此时size = 2.

    list.remove("english");

    那么这时候再次执行下面的判断

    while (iterator.hasNext()) {

    此时cursor的值是3,但是size的值是2,两者不相等,所以hasNext()方法返回true,意味着集合中还有元素,所以还会执行一次next()方法,此时执行checkForComodification()方法,判断modCount是否等于expectedModCount,(expectedModCount=3, modCount=4),两者不相等,所以这就抛出了并发修改异常。

    小结论:

    • 1.集合每次调用add方法时,实际修改次数的值modCount都会自增1;
    • 2.在获取迭代器的时候,集合只会执行一次将实际修改集合的次数modCount的值赋值给预期修改的次数变量expectedModCount;
    • 3.集合在删除元素的时候,也会针对实际修改次数modCount的变量进行自增操作; 

    下面再来看一个并发修改异常的特殊情况,观察下面的程序:

    示例:已知集合中有三个元素:"chinese"、"math"、"english",使用迭代器进行遍历,判断集合中存在"math",如果存在则删除。

    public class TestConcurrentModifyException {
        public static void main(String[] args) {
            List<String> list = new ArrayList<>();
            list.add("chinese");
            list.add("math");
            list.add("english");
            Iterator<String> iterator = list.iterator();
            while (iterator.hasNext()) {
                String nextElement = iterator.next();
                if ("math".equals(nextElement)) {
                    //使用ArrayList的boolean remove(Object o)方法进行删除
                    list.remove("math");
                }
            }
            System.out.println(list);
        }
    }

    我们可以看到,这个示例跟上面一个实例非常相似,唯一不同的是这次删除的元素是集合中的倒数第二个元素。

    程序运行结果:

    [chinese, english]

    我们看到,这里并没有发生并发修改异常,很神奇,而且成功删除”math“这个元素,这是为什么呢?上面一个示例明明说了会发生并发修改异常。下面我们还是分析一下其中的特殊原因: 

    第一次调用hasNext(): cursor = 0    size = 3, hasNext()返回true
    第一次调用iterator.next():
        第一次调用checkForComodification():modCount = 3  expectedModCount = 3
    由于 modCount = expectedModCount ,不会发生并发修改异常。
    第一次next()方法调用完,cursor游标的值会加一,所以cursor = 1. 
    
    ===============================================================================================================
    第二次调用hasNext(): cursor = 1  size = 3, hasNext()返回true
    第二次调用iterator.next():
        第二次调用checkForComodification():modCount = 3  expectedModCount = 3
    由于 modCount = expectedModCount ,不会发生并发修改异常。
    第二次next()方法调用完,cursor游标的值会加一,所以cursor = 2. 
    由于上面的示例中,"math"元素刚好在第二个,所以这时候"math".equals(nextElement)会返回true,
    所以会执行集合的删除元素方法,size会减一,实际修改次数modCount会加一,所以size = 2  modCount = 4
    
    ps:这里注意cursor游标的值也是2,size的值也是2,
    
    ===============================================================================================================
    第三次调用hasNext(): cursor = 2  size = 2, 两者相等,所以hasNext()返回false,while循环结束,意味着不会调用next()方法,
    不会执行调用checkForComodification()方法,那么肯定就不会发生并发修改异常。

    小结论:

    • 当要删除的元素在集合中的倒数第二个元素的时候,删除元素不会产生并发修改异常。
    • 原因:因为在调用hasNext()方法的时候,cursor = size是相等的,hasNext()方法会返回false, 所以不会执行next()方法,也就不会调用checkForComodification()方法,就不会发生并发修改异常。 

    四、如何避免并发修改异常?

    如何避免并发修改异常还有它的特殊情况呢,其实Iterator迭代器里面已经提供了remove(),用于在迭代过程对集合结构进行修改,使用iterator.remove()不会产生并发修改异常,为什么迭代器的删除方法不会产生异常呢,我们得去看看Itr内部类的remove()源码:

    //迭代器自带的删除方法
    public void remove() {
        if (lastRet < 0)
            throw new IllegalStateException();
        //校验是否产生并发修改异常    
        checkForComodification();
    
        try {
              //真正删除元素的方法还是调用的ArrayList的删除方法
             //根据索引进行删除
             ArrayList.this.remove(lastRet);
            
            cursor = lastRet;
            lastRet = -1;
            //每次删除完成后,会重新将expectedModCount重新赋值,值就是实际修改次数modCount的值
            //这就保证了,实际修改次数modCount一定会等于预期修改次数expectedModCount ,所以不会产生并发修改异常.
            expectedModCount = modCount;
        } catch (IndexOutOfBoundsException ex) {
            throw new ConcurrentModificationException();
        }
    }

    小结论:

    • 迭代器调用remove()方法删除元素,底层还是调用的集合的删除元素的方法;
    • 在调用remove()方法后,都会将modCount的值赋值给expectedModCount,保证了它两的值永远都是相等的,所以也就不会产生并发修改异常; 

    五、总结

    以上通过几个示例讲解了并发修改异常的现象,以及分析了并发修改异常是如何产生的,在实际工作中,如果需要使用到删除集合中元素,那么我们不要使用集合自带的删除方法,我们应该使用iterator迭代器给我们提供的删除方法,这样可以很大程序避免程序发生并发修改异常ConcurrentModificationException。

    展开全文
  • Java并发修改异常

    千次阅读 2017-11-28 17:10:44
    今天突然有人问我并发修改异常怎么回事,当时只记得解决方案,不是很详细的知道底层原因,花了一点点时间,看了下源码,发现其实很简单。以下是我的见解 在Java开发中Exception in thread "main" java....
    
     

    今天突然有人问我并发修改异常怎么回事,当时只记得解决方案,不是很详细的知道底层原因,花了一点点时间,看了下源码,发现其实很简单。以下是我的见解

    在Java开发中Exception in thread "main" java.util.ConcurrentModificationException, 这是一个并发修改异常,主要原因是迭代器遍历元素的时候,通过集合是不能修改元素的

     

    假设我们要实现这样一个例子: 判断集合里面有没有"world"这个元素,如果有,就添加一个"javaee"元素

    出现异常的代码如下:

    import java.util.ArrayList;
    import java.util.Iterator;
    
    public class Test {
    
        public static void main(String[] args) {
            ArrayList<String> array = new ArrayList<String>();
    
            // 创建并添加元素
            array.add("hello");
            array.add("world");
            array.add("java");
            Iterator it = array.iterator();
            while (it.hasNext()) {
                String s = (String) it.next();
                if ("world".equals(s)) {
                    array.add("javaee");
                }
            }
        }
    }

    1.异常解释

    • ConcurrentModificationException:当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。
    • 产生的原因:
         迭代器是依赖于集合而存在的,在判断成功后,集合的中新添加了元素,而迭代器却不知道,所以就报错了,这个错叫并发修改异常。
         简单描述就是:迭代器遍历元素的时候,通过集合是不能修改元素的。
    • 如何解决呢?
         A:迭代器迭代元素,迭代器修改元素
         B:集合遍历元素,集合修改元素(普通for)

    2.下面用两种方法去解决这个异常

    import java.util.ArrayList;
    
    public class Test {
    
        public static void main(String[] args) {
            ArrayList<String> array = new ArrayList<String>();
    
            // 创建并添加元素
            array.add("hello");
            array.add("world");
            array.add("java");
            // 方式1:迭代器迭代元素,迭代器修改元素
            // 而Iterator迭代器却没有添加功能,所以我们使用其子接口ListIterator
            // ListIterator lit = array.listIterator();
            // while (lit.hasNext()) {
            // String s = (String) lit.next();
            // if ("world".equals(s)) {
            // lit.add("javaee");
            // }
            // }
            // System.out.println("list1:" + array);
            // 方式2:集合遍历元素,集合修改元素(普通for)
             for (int x = 0; x < array.size(); x++) {
             String s = (String) array.get(x);
             if ("world".equals(s)) {
             array.add("javaee");
             }
             }
    
             System.out.println("list2:" + array);
    
            // 方式3:增强for循环
            // 增强for循环写的话会报同样的错误,因为它本身就是用来替代迭代器的
            // for (String s : array) {
            // if ("world".equals(s)) {
            // array.add("javaee");
            // }
            // }
            // System.out.println("list3:" + array);
        }
    }
    
    
    提示:集合有个属性modCount,每当对集合修改一次,modCount的值就会自增,,迭代器在遍历的时候,底层会new一个Itr的内部类,初始化了一个变量记录了集合的modCount值,
    此变量名是expectedModCount。迭代器在调用next()方法时候会去比较这两个值是否相等,不相等则抛出异常
    
     
    final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); }

     

    https://blog.csdn.net/qq_29534705/article/details/80899351

    展开全文
  • 并发修改异常是指当方法检测到对象的并发修改,但不允许这种修改时抛出的异常,例如有一个ArrayList集合,当检测到里面含有hello时,在hello的后面插入world: 此时就会抛出并发修改异常,这是因为在用迭代器进行...

    并发修改异常是指当方法检测到对象的并发修改,但不允许这种修改时抛出的异常,例如有一个ArrayList集合,当检测到里面含有hello时,在hello的后面插入world:
    这里写图片描述
    此时就会抛出并发修改异常,这是因为在用迭代器进行遍历集合时同时在增加元素,需要注意的是,增强for循环底层也是用的迭代器,所以也不能在遍历是修改值,此时有两种方法解决这个问题:
    一:使用ListIterator进行迭代
    这里写图片描述

    二:用get方法进行遍历:
    这里写图片描述

    展开全文
  • java并发修改异常

    2018-11-29 22:50:51
    并发修改异常 案例1,ArrayList的并发修改 import java.util.ArrayList; public class Test01 { public static void main(String[] args) { ArrayList&lt;String&gt; list = new ArrayList&lt;&...
  • Java中的并发修改异常

    2020-06-04 08:34:27
    关于并发修改异常问题的剖析 迭代器遍历元素的过程中,通过集合是不能修改元素的,否则会出现并发修改异常。(java.util.ConcurrentModificationException) 案例: public class demo2 { public static void main...
  • List集合一、List遍历方式1、Iterator迭代器遍历2、ListIterator迭代器遍历3、for循环和增强for遍历二、并发修改异常1、异常原因2、异常解决办法 一、List遍历方式 1、Iterator迭代器遍历 2、ListIterator迭代器...
  • Java并发修改异常的源码解析

    千次阅读 2018-07-03 15:31:01
    Java并发修改异常的源码解析 1. 什么时候会产生并发修改异常 并发的意思是同时发生,那么其实并发修改的字面意思就是同时修改,通过查看JDK的API我们可以得知,并发修改异常的出现的原因是:当方法检测到对象的...
  • 集合的并发修改异常理解

    千次阅读 2018-02-03 23:20:40
    java.util.ConcurrentModificationExcepton 并发修改异常 /* 集合中的并发修改异常的理解 1、为什么会出现并发修改异常呢?  因为集合在遍历时,你突然修改了集合中的一个值,或添加,引起索引混乱出现并发异常 ...
  • 迭代器并发修改异常

    2018-03-30 09:01:48
    1 迭代器并发修改异常 java.util.ConcurrentModificationException 就是在遍历的过程中,使用了集合方法修改了集合的长度,不允许的; import java.util.ArrayList; import java.util.Iterator; import java....
  • 并发修改异常: 当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。 // ConcurrentModificationException 产生的原因: 迭代器是依赖于集合而存在的,在判断成功之后,集合当中增加了新的元素,而...
  • Java之 Iterator的并发修改异常

    千次阅读 2018-05-19 17:50:46
    在用迭代器遍历容器的时候,试图去修改容器中的元素,可能会引起并发修改异常
  • HashMap并发修改异常解决办法

    千次阅读 2017-04-20 19:18:56
    我在循环读取hashmap里的内容时,在循环中又在另外一个线程对hashmap...翻译过来就是并发修改异常,上网找了下资料,解决方法如下: 调用HashMap的reomve方法时会出现 java.util.ConcurrentModificationExcepti
  • java.util.ConcurrentModificationException并发修改异常 并发修改异常 在集合操作中如果使用迭代器去遍历集合中的元素经常会遇到并发修改异常java.util.ConcurrentModificationException 引发这个问题的主要...
  • 集合修改异常:ConcurrentModificationException with LinkedHashMap ref: https://stackoverflow.com/questions/16180568/concurrentmodificationexception-with-linkedhashmap 项目中并没有对集合进行修改操作,...
  • 文章目录并发修改异常产生的原因及解决方案A:案例演示需求:我有一个集合,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现。ConcurrentModificationException出现解决...
  • java.util.ConcurrentModificationException并发修改异常 多线程并发操作ArrayList时,争抢修改,导致的异常 二,解决方案 ①Collections.syncronizedSet(new HashSet<>()). ②new CopyOnWriteArraySet<>...
  • 并发修改异常原理与解决方法

    千次阅读 2017-06-20 17:22:04
    什么是并发修改异常: 当我们在遍历实现了collection接口与iterator接口的集合时(List、Set、Map), 我们可以通过遍历索引也可以通过迭代器进行遍历。在我们使用迭代器进行遍历集合的时候,会获取到当前集合的迭代...
  • 一,故障现象 java.util…ConcurrentModificationException并发修改异常 二,解决方案 ① new ConcurrentHashMap<>(); ②Collections.syncronizedMap(new HashMap()) 与前面体系一样 ...
  • 使用list.iterator()会发生并发修改异常 代码如下: 解决方案:使用ListIterator迭代器
  • 关于hive中explode函数可能出现的问题之并发修改异常 今天运行hive的sql时,运行一段时间后报错, 如下 Hive Runtime Error while processing row (tag=0) {“key”:{“reducesinkkey0”:13199833},“value”:{"_...
  • EntityFramework 导航属性一对一修改异常。类A中存有类B(类B对象做为类A的一个属性),修改对象A对应的B对象时异常。 ![图片说明](https://img-ask.csdn.net/upload/201605/18/1463539506_283499.png)
  • 迭代器并发修改异常的问题
  • 并发修改异常:当遍历集合的同时,又向集合添加(或删除)元素,就可能报并发修改异常(List体系) 解决方法一:列表迭代器,用列表迭代器的添加add(或删除remove)方法 解决方法二:采用...
  • 在今天看视频的时候讲到修改集合元素的时候会出现并发修改异常就是像这样ArrayList<Integer> list = new ArrayList(); list.add(1); for(int i:list){ list.remove(i); }此时就会报并发修改异常 因为你在进入循环的...
  • 当迭代器操作的时候,如果发现和集合不一样,则抛出异常(并发修改异常) Exception in thread “main” java.util.ConcurrentModificationException:并发修改异常解决方案: &amp;nbsp; &amp;nb...
  • 集合类并发修改异常的解决方案及内部实现 new Vector() add方法中使用synchronized关键字解决了并发修改异常,但并发度下降 public synchronized void addElement(E obj) { modCount++; ensureCapacityHelper...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 21,991
精华内容 8,796
关键字:

修改异常