- 浏览: 172283 次
- 性别:
- 来自: 北京
最新评论
-
chainhou:
sunshineman 写道maven 编译不过啊,连不上ec ...
jetty的下载,编译,安装等 -
sunshineman:
maven 编译不过啊,连不上eclipse的proxy
jetty的下载,编译,安装等
java中出现的ConcurrentModificationException产生原因,解决方式及其它
- 博客分类:
- 常见问题
JAVA开发中有时会出现ConcurrentModificationException,该异常是由于在遍历Collection的时候做了删除或者增加的操作,此时原来统计的size和新的size并不一致,产生了该异常。下面是stackOverflow上的解释:
Here's why: As it is says in the Javadoc:
The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException.
This check is done in the next() method of the iterator (as you can see by the stacktrace). But we will reach the next() method only if hasNext() delivered true, which is what is called by the for each to check if the boundary is met. In your remove method, when hasNext() checks if it needs to return another element, it will see that it returned two elements, and now after one element was removed the list only contains two elements. So all is peachy and we are done with iterating. The check for concurrent modifications does not occur, as this is done in the next() method which is never called.
Next we get to the second loop. After we remove the second number the hasNext method will check again if can return more values. It has returned two values already, but the list now only contains one. But the code here is:
public boolean hasNext() {
return cursor != size();
}
1 != 2, so we continue to the next() method, which now realizes that someone has been messing with the list and fires the exception.
Hope that clears your question up.
要解决该问题,网上也有不少文章。大都谈的是在一个线程中遍历Collection,同时进行删除操作,建议是使用Iterator#remove()方法,而不是其remove(Obj)方法。但如果是多线程的情况下,即使一个线程中使用了Iterator#remove()方法改变了某个Collection,而另一个线程正在遍历该Collection,还是会产生相同的问题。
所以解决办法是需要给两个线程中使用到该Collection的地方都加锁,可以锁定Collection,或者锁定包含Collection的类。
而解决在遍历时会增加的情况,可以将List改为CopyOnWriteArrayList,Map改为相应的同步版本ConcurrentHashMap 即可。
引用
Here's why: As it is says in the Javadoc:
The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException.
This check is done in the next() method of the iterator (as you can see by the stacktrace). But we will reach the next() method only if hasNext() delivered true, which is what is called by the for each to check if the boundary is met. In your remove method, when hasNext() checks if it needs to return another element, it will see that it returned two elements, and now after one element was removed the list only contains two elements. So all is peachy and we are done with iterating. The check for concurrent modifications does not occur, as this is done in the next() method which is never called.
Next we get to the second loop. After we remove the second number the hasNext method will check again if can return more values. It has returned two values already, but the list now only contains one. But the code here is:
public boolean hasNext() {
return cursor != size();
}
1 != 2, so we continue to the next() method, which now realizes that someone has been messing with the list and fires the exception.
Hope that clears your question up.
要解决该问题,网上也有不少文章。大都谈的是在一个线程中遍历Collection,同时进行删除操作,建议是使用Iterator#remove()方法,而不是其remove(Obj)方法。但如果是多线程的情况下,即使一个线程中使用了Iterator#remove()方法改变了某个Collection,而另一个线程正在遍历该Collection,还是会产生相同的问题。
所以解决办法是需要给两个线程中使用到该Collection的地方都加锁,可以锁定Collection,或者锁定包含Collection的类。
而解决在遍历时会增加的情况,可以将List改为CopyOnWriteArrayList,Map改为相应的同步版本ConcurrentHashMap 即可。
发表评论
-
java
2014-05-26 17:36 0http://hi.baidu.com/jiajiajava ... -
JAVA中的线程状态都有哪些?
2014-05-04 10:38 0经常会遇到这样的问题,JAVA中的线程都有哪些状态? 通过du ... -
java.lang.IllegalStateException: The request associated with the AsyncContext ha
2013-12-27 11:09 5508在使用Servlet3.0的异步特性时,免不了会遇到下面这个异 ... -
The display name was defined in multiple fragments with different values includi
2013-12-06 11:13 3221在使用Servlet3.0的新特性中关于WebFragment ... -
java.lang.IllegalStateException: Not supported.at org.apache.catalina.connector.
2013-12-04 14:30 3905在使用Servlet3.0的异步特性的时候,经常会遇到如下异步 ... -
windows中有用的查找端口占用的命令
2013-07-19 15:43 1073在windows中可以使用如下命令,查看端口昌被哪个程序占用。 ... -
ClientCommunicatorAdmin restart/Checker-run 等异常的处理
2013-07-15 19:32 3777在做JMX相关的开发过程中,下面这个异常一个会遇到: 20 ... -
Apache启动异常:apache service unable to open logs
2013-07-04 15:09 7394当启动Apache时,如果弹出窗口提示引用unable to ... -
VBox异常退出后,不能启动问题的解决办法
2013-06-26 15:01 6670今天把VBox中的进程强制停止后,启动VBox的时候,Ubun ... -
InetAddress.getLocalHost().getHostAddress()获取的IP不正确
2013-06-09 17:43 10436今天把在Windows下运行很正常的程序拿到Linux下测试, ... -
获取JVM的所有可选参数
2013-05-30 17:54 915使用如下命令可以列出所有java可选的参数 java -XX: ... -
在windows中获取某个进程的具体执行路径
2013-05-20 17:55 2223经常遇到要处理某类问题,知道某个具体进程,但是却不知道真正的执 ... -
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is
2013-05-08 17:49 2771今天在学RMI的时候遇到了这个问题: java.rmi.Un ... -
java中的toString()和(String)obj的区别
2013-04-22 18:07 1667java中的toString()和(String)obj的区别 ... -
Struts2 Dispatcher initialization failed No mapping found for dependency default
2013-04-10 16:41 1149在struts2的使用时如果发现以下异常信息, 严重: D ... -
java debug
2013-03-27 06:46 8591、 条件断点 断点大家都比较熟悉,在Eclipse Jav ... -
Java远程调试 java -Xdebug各参数说明
2013-03-27 06:43 11532首先,JAVA自身支持调试功能,并提供了一个简单的调试工具-- ... -
jdk Logger引起的NullPointerException
2013-03-25 18:22 968我们平时调用JDK的log来记录日志,都会习惯拿到一个logg ... -
对于应用服务器中的虚拟主机设置别名后,使用别名访问应用
2013-01-21 17:36 1451对于应用服务器中的虚拟主机设置别名后,使用http://别名 ... -
java.lang.IllegalStateException: Post too large的产生原因及解决方式
2013-01-10 18:35 3514最近客户那出了该异常: java.lang.Illegal ...
相关推荐
java.util.ConcurrentModificationException 异常问题详解1
主要介绍了出现java.util.ConcurrentModificationException 问题及解决办法的相关资料,需要的朋友可以参考下
java.util.ConcurrentModificationException 解决方法 在使用iterator.hasNext()操作迭代器的时候,如果此时迭代的对象发生改变,比如插入了新数据,或者有数据被删除。 则使用会报以下异常: Java.util....
NULL 博文链接:https://chenlinbo.iteye.com/blog/832335
今天小编就为大家分享一篇关于Java源码解析ArrayList及ConcurrentModificationException,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
Map在遍历时候通常 现获得其键值的集合Set,然后用迭代器Iterator来对Map进行遍历。
9.Java中访问数据库的步骤,Statement和PreparedStatement之间的区别。 10.找出下列代码可能存在的错误,并说明原因: 二、JSP&Servlet技术 1.描述JSP和Servlet的区别、共同点、各自应用的范围 2.在Web开发中...
java.util.ConcurrentModificationException: mutation occurred during iteration [error] scala.collection.mutable.MutationTracker$.checkMutations(MutationTracker.scala:43) [error] scala.collection....
与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...
Spring数据mongodb测试 在Collections.synchronizedList或Collections.synchronizedSet上测试spring数据mongodb ConcurrentModificationException
下面的考题是我搜集的一些针对java的面试题目,还不少,大概分为[基础类][应用类][其他类],仅供参考,大家还可以说说自己的面试经历。其中另附其它常见内容,包括一些关于数据库的内容。runtime exception。 ...
与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...
axis1.4补丁包,解决jdk1.8高并发报ConcurrentModificationException问题,该jar包重新编译jar包的一个class文件,线上环境通过
CopyOnWriteArraySet 是Java中的一个线程安全的集合类,它实现了 Set 接口并使用了"写时复制"的机制。 下面是关于 CopyOnWriteArraySet 的一些重要信息: 线程安全性:CopyOnWriteArraySet 是线程安全的,可以在多...
java中,List在遍历的时候,如果被修改了会抛出java.util.ConcurrentModificationException错误。 看如下代码: import java.util.ArrayList; import java.util.List; public class Resource3 { public ...
避免在循环中修改集合,可能导致ConcurrentModificationException。 异常处理: 不要忽视异常,合理捕获并处理它们。 不要过度使用try-catch,应尽量抛出业务异常给上层处理。 使用finally块进行资源清理。 并发...
java集合 线程不安全的集合 HashMap的特点 HashMap的长度(容量)为什么要设计成2的幂? HashTable的特点 TreeMap ArrayList的特点 Vector的特点 LinkedList的特点 Set ConcurrentModificationException异常 线程...
axis1.4 spring3.0 集成 实现 web service 服务端, axis1.4 客户端认证,授权,访问日志记录,集成spring 解决 PHP 调用web service 无法认证,和解析soap 模板