文档章节

java.util.ConcurrentModificationException原因

We911
 We911
发布于 2017/02/08 10:17
字数 477
阅读 8
收藏 0
点赞 0
评论 0
Java代码   收藏代码
  1. 用iterator遍历集合时要注意的地方:不可以对iterator相关的地方做添加或删除操作。  
  2.   
  3. 下面用List为例来说明为什么会报 ConcurrentModificationException  这个异常,其它集合类似可以自己思考。  
  4.   
  5.    
  6.   
  7. public static void main(String[] args){  
  8.   List<String> set = new ArrayList<String>();  
  9.   set.add("a10001");  
  10.   set.add("a10002");  
  11.   set.add("a10003");  
  12.   set.add("a10004");  
  13.   set.add("a10005");  
  14.   set.add("a10006");  
  15.   set.add("a10007");  
  16.     
  17.   List<String> del = new ArrayList<String>();  
  18.   del.add("a10003");  
  19.   del.add("a10004");  
  20.   del.add("a10005");  
  21.     
  22.   for(String str : set)  
  23.   {  
  24.    if(del.contains(str))  
  25.    {  
  26.     set.remove(str);  
  27.    }  
  28.   }  
  29.  }  
  30.   
  31.    
  32.   
  33. 运行这段代码的结果  
  34.   
  35.    
  36.   
  37. Exception in thread "main" java.util.ConcurrentModificationException  
  38.  at java.util.AbstractList$Itr.checkForComodification(Unknown Source)  
  39.  at java.util.AbstractList$Itr.next(Unknown Source)  
  40.  at com.debug.Debug.main(Debug.java:28)  
  41.   
  42.    
  43.   
  44. 大家都知道for(String str : set) 这句话实际上是用到了集合的iterator() 方法  
  45.   
  46. 在iterator的时候是产生了一个List的内部类Itr   
  47.   
  48. JDK源码  
  49.   
  50. public Iterator<E> iterator() {  
  51.    return new Itr();  
  52. }  
  53.   
  54. new Itr()时有一个关键性的操作   
  55.   
  56. /** 
  57.   * The modCount value that the iterator believes that the backing 
  58.   * List should have.  If this expectation is violated, the iterator 
  59.   * has detected concurrent modification. 
  60.   */  
  61.  int expectedModCount = modCount;  
  62.   
  63.    
  64.   
  65. 再回头看一下List 的 remove方法  
  66.   
  67.  public boolean remove(Object o) {  
  68.  if (o == null) {  
  69.             for (int index = 0; index < size; index++)  
  70.   if (elementData[index] == null) {  
  71.       fastRemove(index);  
  72.       return true;  
  73.   }  
  74.  } else {  
  75.      for (int index = 0; index < size; index++)  
  76.   if (o.equals(elementData[index])) {  
  77.       fastRemove(index);  
  78.       return true;  
  79.   }  
  80.         }  
  81.  return false;  
  82.     }  
  83.   
  84.    
  85.   
  86. private void fastRemove(int index) {  
  87.         modCount++;  
  88.         int numMoved = size - index - 1;  
  89.         if (numMoved > 0)  
  90.             System.arraycopy(elementData, index+1, elementData, index,  
  91.                              numMoved);  
  92.         elementData[--size] = null// Let gc do its work  
  93.     }  
  94.   
  95.    
  96.   
  97. 再看一下 iterator.next()操作  
  98.   
  99. public E next() {  
  100.             checkForComodification();  
  101.      try {  
  102.   E next = get(cursor);  
  103.   lastRet = cursor++;  
  104.   return next;  
  105.      } catch (IndexOutOfBoundsException e) {  
  106.   checkForComodification();  
  107.   throw new NoSuchElementException();  
  108.      }  
  109.  }  
  110.   
  111.    
  112.   
  113. final void checkForComodification() {  
  114.      if (modCount != expectedModCount)  
  115.   throw new ConcurrentModificationException();  
  116.  }  
  117.   
  118.    
  119.   
  120. 相信看到这儿大家已经应该明白了为什么会出现在这个异常了。  
  121.   
  122. 总结:  
  123.   
  124.   iterator 时 将expectedModCount = modCount 在remove()时 modCount++ 在next()时  
  125.   
  126.  if (modCount != expectedModCount)  
  127.   throw new ConcurrentModificationException();  
  128.   
  129.    
  130.   
  131. 一旦删除或添加元素后 modCount ,expectedModCount 这两个值就会不一致 当next时就会报ConcurrentModificationException   
  132.   
  133.    
  134.   
  135.   
  136. 了解了原由,解决方案就很简单了 在遍历时用一个集合存放要删除的对象 在遍历完后 调用removeAll(Collection<?> c) 就OK了。  

本文转载自:http://blog.csdn.net/liduanw/article/details/8180443

共有 人打赏支持
We911
粉丝 0
博文 63
码字总数 0
作品 0
深圳
程序员
java.util.ConcurrentModificationException异常详解

一、问题发现 在迭代集合元素时,如果对集合做add/remove操作,会抛出java.util.ConcurrentModificationException异常。 如下代码所示: 执行上诉代码,会抛出异常: 这是为什么呢? 二、问题...

最王座
2016/07/06
83
0
java.util.ConcurrentModificationException异常

原文地址:ConcurrentModificationException异常解决办法作者:心灵征途java.util.ConcurrentModificationException异常(转)1、今天在写一个带缓存功能的访问代理程序时出现了java.util.C...

_flowers
2013/11/18
0
0
Java中容器的迭代器的fail-fast机制

Iterator<Integer> keys = gradeMap.keySet().iterator(); while(keys.hasNext()){ Integer i = keys.next(); if(!gradesIds.contains(i)){ // keys.remove(); gradeMap.remove(i); } } 调用......

GreenDay
2014/02/23
0
0
在Android上做List Remove的时候遇到的异常

目的是从createdList里面找到匹配的pendingStatusList,并将其从pendingStatusList中remove for (DocSyncStatus pendingDss : pendingStatusList) { 上述代码会报异常: java.util.Concurre......

Jerikc
2015/04/28
0
0
CopyOnWriteArrayList详解

CopyOnWriteArrayList是ArrayList 的一个线程安全的变体,其中所有可变操作(add、set等等)都是通过对底层数组进行一次新的复制来实现的。 这一般需要很大的开销,但是当遍历操作的数量大大...

古月楼
2013/10/08
0
7
ArrayList用foreach删除元素产生异常

有个ArrayList ArrayList list = new ArrayList(); 当在foreach list时删除一个list中的元素就会出现 java.util.ConcurrentModificationException ,像这样: 原因是 ArrayList有个modCount字......

SwordHua
2013/12/13
0
0
理解和解决Java并发修改异常ConcurrentModificationException

your name.jpg 关键字: Java Exception 不知读者在Java开发的过程中有没有遇到类似的异常信息 Exception in thread "main" java.util.ConcurrentModificationException, 下面小编简单介绍异...

RookieDay
2016/12/16
0
0
HashMap出现 java.util.ConcurrentModificationExceptio

Iterator keys = gradeMap.keySet().iterator(); while(keys.hasNext()){ Integer i = keys.next(); if(!gradesIds.contains(i)){ // keys.remove(); gradeMap.remove(i); } } 调用HashMap的......

黄平俊
2009/09/27
5.4K
1
Java ConcurrentModificationException 异常分析与解决方案

一、单线程 1. 异常情况举例 只要抛出出现异常,可以肯定的是代码一定有错误的地方。先来看看都有哪些情况会出现ConcurrentModificationException异常,下面以ArrayList remove 操作进行举例...

LIU-X1001
2016/05/31
28
0
java中,遍历ArrayList的同时删除元素

测试当List下只有一个元素时,在Iterator遍历过程中使用非iterator.remove()方式删除 public class HashMapTest { public static void main(String[] args) { ArrayList al = new ArrayList......

蒋科
2012/09/24
19.6K
18

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Linux服务器下的HTTP抓包分析

说到抓包分析,最简单的办法莫过于在客户端直接安装一个Wireshark或者Fiddler了,但是有时候由于客户端开发人员(可能是第三方)知识欠缺或者其它一些原因,无法顺利的在客户端进行抓包分析,...

mylxsw
5分钟前
0
0
mybatis3-javaapi

sqlSessionFactoryBuilder->sqlSessionFactory->sqlSession<-rowbound<-resultHandler myBatis uses a Java enumeration wrapper for transaction isolation levels, called TransactionIsol......

writeademo
8分钟前
0
0
Java NIO:浅析I/O模型

也许很多朋友在学习NIO的时候都会感觉有点吃力,对里面的很多概念都感觉不是那么明朗。在进入Java NIO编程之前,我们今天先来讨论一些比较基础的知识:I/O模型。下面本文先从同步和异步的概念...

yzbty23
8分钟前
0
0
了解iOS消息推送一文就够:史上最全iOS Push技术详解

本文作者:陈裕发, 腾讯系统测试工程师,由腾讯WeTest整理发表。 1、引言 开发iOS系统中的Push推送,通常有以下3种情况: 1)在线Push:比如QQ、微信等IM界面处于前台时,聊天消息和指令都会...

JackJiang-
10分钟前
0
0
Mysql汉子转拼音

update t_app_city SET CITY_NAME_BEGIN = ELT(INTERVAL(CONV(HEX(LEFT(CONVERT(CITY_NAME USING gbk),1)),16,10), 0xB0A1,0xB0C5,0xB2C1,0xB4EE,0xB6EA,0xB7A2,0xB8C1,0xB9FE,0xBBF7, 0xBFA......

尘叙缘
12分钟前
0
0
大数据构建智慧城市“新引擎”,加速推进新旧动能转换

——“大数据与智慧城市”技术交流分享会——济南站召开 7月13日,“大数据携手智慧城市,助力山东新旧动能转换”技术交流分享会——济南站在山东信息通信技术研究院会议室成功举办,此次会议...

左手的倒影
14分钟前
2
0
tomcat 学习笔记之 Session管理

1、Catalina 通过一个 Session 管理器的组件来管理建立的Session 对象 该组件由 org.apache.catalina.Manager 接口表示 Session 管理器必须与一个 Context 关联 Session 管理器负责,创建、更...

职业搬砖20年
14分钟前
0
0
jquery获取input框的几种方式

//如何用jquery获取<input id="test" name="test" type="text"/>中输入的值?$(" #test ").val()$(" input[ name='test' ] ").val()$(" input[ type='text' ] ").val()$(" input[ ......

gulf
17分钟前
0
0
gradle的环境变量的配置

gradle的环境变量的配置 1.首先下载jdk,并且配置jdk的环境变量. 2.找到自己AS安装gradle的目录 我自己的目录为:F:\Android Studio3.1.3\gradle\gradle-4.4 创建环境变量:GRADLE_PATH: F:\A...

android-key
23分钟前
0
0
saltstack配置apache

1.相关配置 #vim /etc/salt/master //打开如下内容的注释 file_roots: base: - /srv/salt #mkdir /srv/salt #vim /srv/salt/top.sls base: 'slaver.test.com': - apache 注意:若换成 '*',则......

硅谷课堂
24分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部