首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >列表ConcurrentModificationException

列表ConcurrentModificationException
EN

Stack Overflow用户
提问于 2013-10-27 19:56:10
回答 2查看 2.1K关注 0票数 3

我有以下代码

代码语言:javascript
复制
public void saveProjects(List<Project> proj) throws DatabaseException {
    for (Project listItems: proj) { // error here

        insertProjects(listItems);
    }
}

private void insertProjects(Project prj) throws DatabaseException {
    commitObjects(prj);
}

在执行上述操作时,在for (Project listItems: proj) {上将得到以下异常

java.util.AbstractList$Itr.checkForComodification(AbstractList.java:449) at java.util.AbstractList$Itr.next(AbstractList.java:420)的java.util.ConcurrentModificationException

如何使用next或迭代器来解决这个问题?

编辑1

调用saveProjects的代码段

代码语言:javascript
复制
projectList.add(proj);
  for (Project persist: projectList) {
       persist.setProjectId("K7890");
       persist.setName(fileName);

          myDAO.saveProjects(projectList);

     }
  projectList.clear();
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-10-27 19:57:03

从代码

代码语言:javascript
复制
for (Project persist: projectList) { 
     persist.setProjectId("K7890");
     persist.setName(fileName);

      myDAO.saveProjects(projectList); 
 }

projectList.clear(); // <-- clear might cause to this Exception

参考文献

为什么在使用迭代器时会得到ConcurrentModificationException?

java.util Collection类是快速失败的,这意味着如果一个线程在另一个线程使用迭代器遍历集合时更改集合,则iterator.hasNext()iterator.next()调用将抛出ConcurrentModificationException

甚至同步集合包装器类SynchronizedMapSynchronizedList也只是有条件的线程安全,这意味着所有单独的操作都是线程安全的,但是控制流依赖于以前操作的结果的复合操作可能会受到线程问题的影响。(List myList = Collections.synchronizedList (myList)!它可能在这里行不通)

多线程访问情况下的解决方案

解决方案1:您可以使用list.toArray()将列表转换为数组并在数组上迭代。如果列表很大,则不建议使用此方法。

解决方案2:您可以通过在同步块中包装代码来锁定整个列表。如果应用程序高度并发,则此方法会对其可伸缩性产生不利影响。

解决方案3:您可以使用ConcurrentHashMapCopyOnWriteArrayList类,它们提供了更好的可伸缩性,ConcurrentHashMap.iterator()返回的迭代器不会在维护线程安全的同时抛出ConcurrentModificationException

单线程访问情况的解决方案

使用:

代码语言:javascript
复制
it.remove();

它通过Iterator it删除当前对象,Iterator list对基础集合list具有引用。

避免:

代码语言:javascript
复制
list.remove(myObject);
票数 6
EN

Stack Overflow用户

发布于 2013-10-27 20:20:02

看起来很奇怪,我猜您是在迭代时在另一个线程中修改列表(List<Project> proj)吗?

因为您没有在您给我们的代码中以任何方式更改列表。

您可以尝试使用saveProjects列表的副本调用proj方法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19622773

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档