如何修复此错误java.util.ConcurrentModificationException
我在下面的行中得到一个错误。 我正在做添加到jsonarray的过程。 请帮帮我如何修复此错误java.util.ConcurrentModificationException,java,exception,arrays,concurrentmodification,Java,Exception,Arrays,Concurrentmodification,我在下面的行中得到一个错误。 我正在做添加到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(""))
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());
您是否从另一个线程访问jsonArr?i、 e.在修改jsonArr的同时迭代它
当您在迭代集合的同时修改集合时,将引发ConcurrentModificationException。当您在循环中迭代集合并修改相同集合时,将获得ConcurrentModificationException。给定的代码段没有显示这一点,因此在修改集合的上面或下面还有其他内容。尝试在实例化jsonArr的地方声明它 一个可能的原因可能是jsonArr实例对象是类级别的,由多个线程访问。声明实例化jsonArr对象的位置
编辑:将jsonArr设置为局部变量。若要解决此问题,请确保
如果您的集合不是线程安全的,则当其他线程迭代此集合时,不能使用其他线程对其进行修改
有两种可能的方法可以解决此问题-
1) 一种解决方案是同步对集合的所有访问
2) 使用线程安全集合,如CopyOnWriteArrayList
List<String> empList = new CopyOnWriteArrayList<>();
empList.add("Mojtaba");
empList.add("Mojtabye");
empList.add("Yeganeh");
for (String item : empList) {
System.out.println(item);
empList.add("test");
}
来自Java文档-
此异常可能由检测到并发的方法引发
当不允许修改对象时,对对象进行修改
例如,通常不允许一个线程修改
当另一个线程在其上迭代时。总的来说
在这些情况下,迭代的结果是未定义的。一些
迭代器实现(包括所有集合的迭代器实现)
JRE提供的实现可以选择抛出
检测到此行为时发生异常。执行此操作的迭代器是
我们称之为fail fast迭代器,因为它们失败迅速且干净,而不是
在一个不确定的时间里,冒着任意的、不确定的行为的风险
未来的时间
这是我在重新编程时经常遇到的错误。这一例外的原因或细节相当清楚。不允许在迭代集合时修改集合(您正在添加新元素)。至少
的语法不支持这样做
要解决您的问题,我认为有两种方法很简单
1) 。更好的方法是使用迭代器避免ConcurrentModificationException,而不是使用for
语句进行循环
Iterator<Book> 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);
}
}
Iterator Iterator=bookList.Iterator();
while(iterator.hasNext()){
Book c=iterator.next();
if(c.getBookName().startsWith(name)){
JSONObject=新的JSONObject();
put(“label”,c.getBookName());
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);
List List=new ArrayList();
for(c册:GlobalObjects.bookList){
if(c.getBookName().startsWith(name)){
JSONObject=新的JSONObject();
put(“label”,c.getBookName());
put(“value”,c.getId());
list.add(jsonObjec);//java.util.ConcurrentModificationException
}
}
jsonArr.addAll(列表);
或使用允许迭代和修改同一列表的ListIterator
还有一种方法,即
我们可以传递列表的克隆以进行迭代,而不是传递实际的列表
listForIteration=list.clone()
//执行操作..只需使用java.util.concurrent.CopyOnWriteArrayList
List<String> empList = new CopyOnWriteArrayList<>();
empList.add("Mojtaba");
empList.add("Mojtabye");
empList.add("Yeganeh");
for (String item : empList) {
System.out.println(item);
empList.add("test");
}
List empList=new CopyOnWriteArrayList();
雇主添加(“Mojtaba”);
雇主。添加(“Mojtabye”);
雇主。添加(“叶加内”);
for(字符串项:empList){
系统输出打印项次(项);
雇主。添加(“测试”);
}
正如devsundar所说,除非jsonArr是多线程访问的,否则这不会导致CME。是吗?从代码中,我看到jsonArr只是被修改过,而不是同时被访问。如果aliplane在前面提到的那一行得到了CME,那么应该从另一个位置或线程修改jsonArr。到目前为止,您做了哪些尝试?你读过ConcurrentModificationException的JavaDoc吗?你是否遗漏了一些代码,在这些代码中,你实际上也在迭代正在添加项的JSONArray?从Servlet内部访问代码。我使用自动完成功能。在多线程环境(如web应用程序)中编码时,尽可能使变量的范围保持局部。你不会遇到这样的问题。不鼓励只使用链接的答案,因此答案应该是搜索解决方案的终点(而不是另一个参考文献的中途停留,随着时间的推移,这些参考文献往往会过时)。请考虑在这里添加一个独立的概要,将链接作为参考。