gpt4 book ai didi

java - 列出 ConcurrentModificationException

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:27:41 25 4
gpt4 key购买 nike

我有以下代码

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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com