加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 列出ConcurrentModificationException

发布时间:2020-12-15 04:14:52 所属栏目:Java 来源:网络整理
导读:我有以下代码 public void saveProjects(ListProject proj) throws DatabaseException { for (Project listItems: proj) { // error here insertProjects(listItems); }}private void insertProjects(Project prj) throws DatabaseException { commitObjects
我有以下代码

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

当我执行上面的操作时,我得到以下异常(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或with iterator解决此问题?

编辑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集合类是快速失败的,这意味着如果一个线程更改集合而另一个线程使用迭代器遍历它,则iterator.hasNext()或iterator.next()调用将抛出ConcurrentModificationException.

甚至同步的集合包装类SynchronizedMap和SynchronizedList也只是有条件的线程安全的,这意味着所有单独的操作都是线程安全的,但是复合操作,其中控制流取决于先前操作的结果可能受到线程问题的影响. (列出myList = Collections.synchronizedList(myList)!这可能不起作用)

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

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

解决方案2:您可以在迭代时锁定整个列表,方法是将代码包装在同步块中.如果应用程序高度并发,则此方法会对应用程序的可伸缩性产生负面影响

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

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

使用:

it.remove();

它通过Iterator删除当前对象,它具有对底层集合列表的引用.

避免:

list.remove(myObject);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读