如何解决此错误java.util.ConcurrentModificationException
我在下一行收到错误。 我正在做添加到jsonarray的过程。 请帮帮我。
jsonArr=new JSONArray(); if(req.getSession().getAttribute("userses")!=null){ String name=(req.getParameter("name")==null?"":to_EnglishName(req.getParameter("name").toUpperCase())); if(!name.equals("")){ for(Book c:GlobalObjects.bookList){ if(c.getBookName().startsWith(name)){ jsonObjec=new JSONObject(); jsonObjec.put("label",c.getBookName()); jsonObjec.put("value", c.getId()); jsonArr.add(jsonObjec);//java.util.ConcurrentModificationException } } } } jsonArr.write(res.getWriter());
这是我在重新编程时经常遇到的错误。 这个例外的原因或细节非常清楚。 在迭代时不允许修改集合(您正在添加新元素)。 至少DO NOT支持的语法for
这样做的。
为了解决你的问题,我认为有两种方法很简单。
1)。 而不是使用for
语句循环,更好的方法是使用迭代器来避免ConcurrentModificationException。
Iterator iterator = bookList.iterator(); while(iterator.hasNext()){ Book c = iterator.next(); if(c.getBookName().startsWith(name)){ jsonObjec=new JSONObject(); jsonObjec.put("label",c.getBookName()); jsonObjec.put("value", c.getId()); jsonArr.add(jsonObjec); } }
2)。 循环它时,不要添加它。
List list = new ArrayList<>(); for(Book c:GlobalObjects.bookList){ if(c.getBookName().startsWith(name)){ jsonObjec=new JSONObject(); jsonObjec.put("label",c.getBookName()); jsonObjec.put("value", c.getId()); list.add(jsonObjec);//java.util.ConcurrentModificationException } } jsonArr.addAll(list);
要解决此问题,请确保If your collection is not thread safe then it must not get modified with another thread when some other thread is iterating over this collection
。
有两种方法可以解决这个问题 –
1)一种解决方案是同步对集合的所有访问
2)使用像CopyOnWriteArrayList
这样的线程安全集合
来自Java Doc –
当不允许这样的修改时,检测到对象的并发修改的方法可能抛出此exception。
例如,一个线程修改Collection而另一个线程迭代它时通常不允许。 通常,在这些情况下,迭代的结果是不确定的。 如果检测到此行为,某些Iterator实现(包括JRE提供的所有集合实现的实现)可能会选择抛出此exception。 执行此操作的迭代器称为故障快速迭代器,因为它们快速且干净地失败,而不是在未来的未确定时间冒着任意的,非确定性行为的风险。
当您在集合上进行迭代并在循环中修改相同的集合时,会出现ConcurrentModificationException。 给定的代码段没有显示,因此在修改集合之上或之下还有其他内容。 尝试在实例化它的地方声明jsonArr。
一个可能的原因可能是jsonArr实例Object是类级别并且由多个线程访问。 声明实例化jsonArr对象的位置。
编辑:使jsonArr成为局部变量。
你是从另一个线程访问jsonArr吗? 即在同时修改它时迭代jsonArr。
在迭代时同时修改集合时抛出ConcurrentModificationException。
或者使用ListIterator,它允许迭代和修改相同的列表
http://docs.oracle.com/javase/6/docs/api/java/util/ListIterator.html
还有一种方法,即通过实际列表,我们可以通过列表的克隆进行迭代。
listForIteration = list.clone();
//做手术..
只需使用java.util.concurrent.CopyOnWriteArrayList
List empList = new CopyOnWriteArrayList<>(); empList.add("Mojtaba"); empList.add("Mojtabye"); empList.add("Yeganeh"); for (String item : empList) { System.out.println(item); empList.add("test"); }
- JDK8 CompletableFuture.supplyAsync如何处理interruptedException
- java.io.StreamCorruptedException:无效的流标题:00000001
- java线程exception
- 将ExceptionDescribe转换为字符串
- MediaSession finishBroadcast()exception
- Android XML文件java.lang.nullpointerexception
- 如何从容器管理的事务提交中捕获exception?
- 如何在InputMismatchException之后重试输入?
- 为什么简单的select查询返回List 但是在jpa中连接查询返回List