java - 列出 ConcurrentModificationException

标签 java java.util.concurrent concurrentmodification

我有以下代码

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.ConcurrentModificationException at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:449) at java.util.AbstractList$Itr.next(AbstractList.java:420)

如何使用 next 或迭代器解决此问题?

编辑 1

我调用 saveProjects 的代码片段

projectList.add(proj);
  for (Project persist: projectList) {
       persist.setProjectId("K7890");
       persist.setName(fileName);

          myDAO.saveProjects(projectList);

     }
  projectList.clear();

最佳答案

来自代码

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:您可以通过将代码包装在同步块(synchronized block)中来在迭代时锁定整个列表。如果它是高度并发的,这种方法会对应用程序的可扩展性产生不利影响。

解决方案 3:您可以使用 ConcurrentHashMapCopyOnWriteArrayList 类, 它提供了更好的可扩展性,ConcurrentHashMap.iterator() 返回的迭代器不会抛出 ConcurrentModificationException,同时保持线程安全。

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

使用:

it.remove();

它通过迭代器 it 删除当前对象,该迭代器引用了您的基础集合 list

避免:

list.remove(myObject);

关于java - 列出 ConcurrentModificationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19622773/

相关文章:

java - 如何避免 ConcurrentModificationException

java - androidx.gridlayout.widget.GridLayout 无法转换为 android.widget.GridLayout

java - 在一个类中重写多个类的多个方法

java - 如何从字符串中提取值

java - foreach 循环中的 ConcurrentModificationException

java - 随机 java.util.ConcurrentModificationException : null

java - 在 Intellij CE 中,如何显示 Maven 选项卡?

java - 如何暂停执行直到听众完成?

java - 寻找 java.util.Set 的无界、基于队列的并发实现

java - ConcurrentHashMap.newKeySet() 与 Collections.newSetFromMap()