java.util.ConcurrentModificationException

一.collection集合

1.collection集合存在iterator迭代器,作为替代方案出现了增强for

2.list集合中出现了listiterator,listiterator中增加了add()方法,加上iterator之前的remove()方法,可以解决并发修改异常

3.set集合中不存在普通for,因为无序;

注意:并发修改异常出现的原理是,遍历时操作集合,导致集合不一致;

           例如:Arrallist是一个集合,若用iterator或者listiterator遍历时,相当于操作了Arrallist的复制版,当要在遍历删除时,应该用iterator或者listiterator中的remove()方法。

而不能用Arrallist中的方法。

代码:

        

List<Integer> list = new ArrayList<Integer>();
        list.add(1);
        list.add(2);
        list.add(3);
会出现异常情况:

1.

Iterator<Integer> iterator = list.iterator();
        while(iterator.hasNext()) {
            if(iterator.next().equals(2)) {
                list.add(10);
            }
        }
2.
ListIterator<Integer> listIterator = list.listIterator();
        while (listIterator.hasNext()) {
            if (listIterator.next().equals(2)) {      
                  list.add(10);
            }
        }


3.
for(int temp : list) {
            if(temp == 2) {
                list.add(10);
            }
        }
注意:以上均是运用不同对象(list)操作了集合导致异常,

解决方案:
1、增强for无法解决,iterator只有在遍历的同时删除才可解决并发修改异常(用iterator的remove()方法),在遍历的同时添加时,iterator没有添加方法;
listiterator 遍历的同时删除和增加元素都可以,因为listiterator 中有remove()和add()方法;
2.用普通for; 注意 普通for,只是针对list集合(有序集合)出现的,存在get()方法;而set集合是唯一,无序,没有get()方法,不能用普通for。
3.倒序遍历;

不会出现异常情况:
1.
int length = list.size();
        for (int i = 0; i < length; i++) {
            if (list.get(i).equals(2)) {
                list.add(10);
            }
        }
2.
ListIterator<Integer> listIterator = list.listIterator();
        while (listIterator.hasNext()) {
            if (listIterator.next().equals(2)) {
                listIterator.add(10);
            }
        }

注意:若在普通for删除元素时,不要忘记 i--,并且多线程中也许要用普通for解决;
      用listiterator 或者iterator仍然报并发修改异常.

例如:.

for 
( int i = 
0; i < list.size()); i++) {

     
     
      String value = list.get(i);
      System. out.println( "List Value:" + value);
       if (value.equals( "3" )) {
          l ist.remove(value);  // ok
           i--; // 因为位置发生改变,所以必须修改i的位置
      }
}


二.map集合以下为转载 http://doublekj.blog.163.com/blog/static/146818474201251510248918/?COLLCC=1505412599&COLLCC=1387972087&COLLCC=1488635383&COLLCC=1941620215&

调用HashMap的reomve方法时会出现 java.util.ConcurrentModificationException 。

解决方法就是先用Iterator的方法remove,然后再调用HashMap的remove方法。

即代码如下:Iterator<Integer> keys = gradeMap.keySet().iterator();while(keys.hasNext()) {     Integer i = keys.next();     if(!gradesIds.contains(i)) {          keys.remove();          gradeMap.remove(i);

     }

}

我加入这段代码之后,还是会出现该异常,于是继续寻找原因,发现了这样两段话:

1.如果你的程序是高并发,并且你的map是经常修改的,千万不要用HashMap,会把这个线常卡死的,要用ConcurrentHashMap2.虽然HashTable和ConcurrentHashMap都是线程安全的,但是HashTable是同步容器,ConcurrentHashMap是并发容器,

采用了锁分离策略,在并发环境中,应多使用ConcurrentHashMap,因为它具有非常好的并发性能,可以多个线程同时读写。

而HashTable只能同时一个线程读写。 可以简单的把ConcurrentHashMap理解为多个HashMap组合,锁不是在ConcurrentHashMap上,

而是在某个HashMap上。注意:ConcurrentHashMap和HashMap的一个不同点就是ConcurrentHashMap里不能存放key和value为空的值。

于是将Hashmap改为ConcurrentHashMap OK





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值