5

我在下一行收到错误。我正在做添加到 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());
4

7 回答 7

16

这是我在重新编程时经常遇到的错误。此异常的原因或细节非常清楚。迭代时不允许修改集合(您正在添加新元素)。至少语法for不支持这样做。

要解决您的问题,我认为有两种方法很简单。

1)。而不是使用for语句循环,更好的方法是使用迭代器来避免 ConcurrentModificationException。

    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);
        }
    }

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);
于 2012-07-10T08:40:28.887 回答
3

要解决此问题,请确保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 文档 -

当这种修改是不允许的时,检测到对象的并发修改的方法可能会抛出此异常。

例如,通常不允许一个线程在另一个线程对其进行迭代时修改 Collection。一般来说,在这些情况下,迭代的结果是不确定的。如果检测到此行为,某些 Iterator 实现(包括 JRE 提供的所有集合实现的那些)可能会选择抛出此异常。这样做的迭代器被称为快速失败迭代器,因为它们快速而干净地失败,而不是在未来不确定的时间冒着任意的、非确定性的行为的风险。

于 2012-07-10T06:29:42.840 回答
2

当您迭代一个集合并在循环中修改同一个集合时,您会得到 ConcurrentModificationException。给定的代码片段没有显示这一点,因此在修改集合的上方或下方还有其他内容。尝试在实例化它的地方声明 jsonArr。

一个可能的原因可能是 jsonArr 实例 Object 是类级别的并且被多个线程访问。声明实例化它的 jsonArr 对象。

编辑:使 jsonArr 成为局部变量。

于 2012-07-10T06:29:09.340 回答
1

还有另一种方法,即传递实际列表,我们可以传递列表的克隆进行迭代。

listForIteration = list.clone();

//进行操作..

于 2015-12-10T07:11:01.660 回答
0

或者使用允许迭代和修改同一个列表的 ListIterator

http://docs.oracle.com/javase/6/docs/api/java/util/ListIterator.html

于 2013-09-25T11:56:51.877 回答
0

你是从另一个线程访问 jsonArr 吗?即当您同时修改它时迭代jsonArr。

当您在迭代集合的同时修改集合时,会引发 ConcurrentModificationException。

于 2012-07-10T06:24:28.910 回答
0

只需使用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");
}
于 2016-08-17T13:31:06.120 回答