Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何修复此错误java.util.ConcurrentModificationException_Java_Exception_Arrays_Concurrentmodification - Fatal编程技术网

如何修复此错误java.util.ConcurrentModificationException

如何修复此错误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(""))

我在下面的行中得到一个错误。 我正在做添加到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());

您是否从另一个线程访问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应用程序)中编码时,尽可能使变量的范围保持局部。你不会遇到这样的问题。不鼓励只使用链接的答案,因此答案应该是搜索解决方案的终点(而不是另一个参考文献的中途停留,随着时间的推移,这些参考文献往往会过时)。请考虑在这里添加一个独立的概要,将链接作为参考。