关于ConcurrentModificationException异常原因及注意事项
来源:互联网 发布:c语言pdf下载 编辑:程序博客网 时间:2024/05/19 20:01
嗨,大家好!最近在工作中遇到了一个棘手的问题(如题),特此在这里跟大家分享一下,第一次发博客,不足之处大家见谅!
异常出现原因:
ConcurrentModificationException这个异常继承自RuntimeException,见名知意,这个异常一般是在Collection 上进行迭代,检测到对象的并发修改,但不允许这种修改时,抛出此异常,废话不多说,直接上干货,下面是几种出现这种异常的情况:
1、在对集合进行遍历的同时对集合进行修改,例如对Map的遍历(List同样适用),如下代码:
//注:这是编译后的代码,一般对Map集合遍历的代码都会被编译成这个样子 Map<String, Integer> map = new HashMap(); // 省略map的初始化代码 Iterator i = map.entrySet().iterator(); while(i.hasNext()) { Entry<String, Integer> entry = (Entry)i.next(); String key = (String)entry.getKey(); map.remove("a"); //map.add("a",18); ***对集合数据进行修改 String value = ((Integer)entry.getValue()).toString(); System.out.println("key =" + key + " value = " + value); }
2、使用List的subList方法时要注意了(亲身经历委屈),比如从数据库拿到一批数据,进行复杂业务的处理时,需要对List集合进行分割然后起多线程进行处理。subList方法并不会创建新的list对象,本质上只是给你返回了原List的一小段数据的引用,如下(摘自JDK1.8 ArrayList):
SubList(AbstractList<E> parent, int offset, int fromIndex, int toIndex) { this.parent = parent; this.parentOffset = fromIndex; this.offset = offset + fromIndex; this.size = toIndex - fromIndex; this.modCount = ArrayList.this.modCount; }
这种情况下,在多线程对分割后的List1、List2……..等等进行遍历时,如果同时存在修改操作也会出现此异常。
3、一个隐藏很深的大坑奋斗,在对map进行toString的同时修改map,这也是我这次遇到的情况(公司的框架啊!!!)。下面是场景重现:当我对数据库进行分页查询时,会首先根据查询条件(map)进行符合条件的总条目数的查询;关键点来了,查询之后会有一个finally代码块单独从线程池拿一个线程进行日志的打印,日志打印需要的参数其中就包含map.toString。后边我主线程查询完总条目数后会执行一段逻辑,然后会将分页信息添加到map中(分页查询的pageIndex,pageSize)然后在进行分页查询,这就是问题最关键的时刻,前面对map进行toStirng操作,后边又往里面添加数据,在业务量很大的情况下,抛出异常也是在所难免的。
代码简单例子如下(公司代码保密,只能写一个简单例子):
//进行分页查询的主方法 public void mainMethod(Map<String,Object> param,int pageIndex,int pageSize){ int totalCount = queryCount(param); //进行总条目数的查询 //.... //一些业务逻辑 //.... param.put("pageIndex",pageIndex); //问题代码 param.put("pageSize",pageSize); //问题代码 // 进行分页查询 } public int queryCount(Map<String,Object> param){ try { //进行数据库查询然后返回总条目数 }catch (Exception e){ }finally { //在这里从线程池拿线程进行日志的打印 // logger.warn(........param.toStirng()....); } }
总结:对集合进行遍历的同时,尽量不要进行其他修改操作,如果真有业务需要,那就要考虑当前集合是否是最适合的集合?是否应该使用java.util.concurrent包下的线程安全的数据结构呢?
注:欢迎大家回复讨论,谢谢!转载请注明出处。
- 关于ConcurrentModificationException异常原因及注意事项
- ConcurrentModificationException异常产生原因
- ConcurrentModificationException异常原因
- Java ConcurrentModificationException异常原因
- Java之旅--ConcurrentModificationException关于异常原因和解决方法
- ArrayList引起的ConcurrentModificationException 异常原因及解决方法
- ConcurrentModificationException异常原因和解决方法
- ConcurrentModificationException异常产生原因分析
- ConcurrentModificationException异常及解决方案
- 关于list的ConcurrentModificationException 异常
- 关于java.util.ConcurrentModificationException异常
- 发生ConcurrentModificationException异常的原因分析
- Java ConcurrentModificationException异常原因和解决方法
- Java ConcurrentModificationException异常原因和解决方法
- Java ConcurrentModificationException异常原因和解决方法
- Java ConcurrentModificationException异常原因和解决方法
- Java ConcurrentModificationException异常原因和解决方法
- Java ConcurrentModificationException异常原因和解决方法
- Logger.getLogger()和LogFactory.getLog()的区别
- [笔记]PHP语法基础备忘
- M
- HDU 1570 AC
- bi数据仓库的架构与设计基础
- 关于ConcurrentModificationException异常原因及注意事项
- 22.列表对话框AlertDialog.Builder:省份选择列表
- 暨南大学课程评估自动化脚本
- DCT算法的原理和优化
- 多线程
- Android下pm 命令详解
- Servlet forward 和 sendRedirect 的区别
- 解决弹出层时底部body点击不滑动
- 版本管理工具介绍—Git篇