【问题标题】:How can I fix this error java.util.ConcurrentModificationException如何修复此错误 java.util.ConcurrentModificationException
【发布时间】:2012-07-09 14:14:35
【问题描述】:

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

【问题讨论】:

  • 到目前为止你尝试过什么?你读过 ConcurrentModificationException 的 JavaDoc 吗?
  • 您是否遗漏了一些代码,在这些代码中您实际上也在迭代要添加项目的 JSONArray?

标签: java exception arrays concurrentmodification


【解决方案1】:

这是我在重新编程时经常遇到的错误。此异常的原因或细节非常清楚。迭代时不允许修改集合(您正在添加新元素)。至少语法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);

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

      • 从 Servlet 内部访问代码。我使用自动完成功能。
      • 在多线程环境(如 Web 应用程序)中编码时,尽可能将变量的范围保持在本地。您不会遇到此类问题。
      【解决方案4】:

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

      listForIteration = list.clone();

      //做操作..

      【讨论】:

        【解决方案5】:

        你是从另一个线程访问 jsonArr 吗?即同时修改 jsonArr 时对其进行迭代。

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

        【讨论】:

        • 正如 devsundar 所说,这不应该导致 CME,除非 jsonArr 被多线程访问。是吗?
        • 从代码中我看到 jsonArr 只是被修改了,它没有被同时访问。如果 aliplane 在提到的那一行得到 CME,那么 jsonArr 应该从另一个位置或线程修改。
        【解决方案6】:

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

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

        【讨论】:

        • 不鼓励仅链接的答案,因此答案应该是搜索解决方案的终点(相对于另一个参考中途停留,随着时间的推移往往会变得陈旧)。请考虑在此处添加独立的概要,保留链接作为参考
        【解决方案7】:

        只需使用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-11-17
          • 2013-11-08
          • 1970-01-01
          • 2012-05-19
          • 1970-01-01
          • 1970-01-01
          • 2020-02-22
          • 2014-03-01
          • 1970-01-01
          相关资源
          最近更新 更多