如何解决此错误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"); }