Java List集合并发修改异常的出现和处理

当我们在Java中对list集合内的元素进行增加、删除或修改操作的时候容易出现并发修改异常(ConcurrentModificationException),以下是个人总结的出现原因以及解决方法,如有错误,请及时指出。

出现原因:

  1. 在迭代器内遍历集合时,直接对集合元素进行操作。

  1. 使用foreach(增强for循环)遍历集合时,直接对集合元素进行操作。

注意:其实Java中的增强for循环底层是通过迭代器模式来实现的。

错误示例:

public static void main(String[] args) {
    //创建集合对象
    List<String> list = new ArrayList<>();

    //添加元素
    list.add("hello");
    list.add("world");
    list.add("java");

    //使用迭代器添加集合元素,ConcurrentModificationException
    Iterator<String> li = list.iterator();
    while (li.hasNext()) {
        String s = li.next();
        if (s.equals("world")) {
            list.add("javascript");
        }
    }
    
    //使用集合迭代器删除集合元素,ConcurrentModificationException
    ListIterator<String> lit = list.listIterator();
    while (lit.hasNext()) {
        String s = lit.next();
        if (s.equals("world")) {
            list.remove("javascript");
        }
    }

    //使用foreach遍历修改集合元素,ConcurrentModificationException
    for (String s : list) {
        if (s.equals("world")) {
            list.remove("world");
            list.add("javascript");
        }
    }
}

解决方法:

  1. 使用迭代器遍历集合来操作集合元素时,使用迭代器内提供的方法

public static void main(String[] args) {
    //创建集合对象
    List<String> list = new ArrayList<>();
    
    //添加元素
    list.add("hello");
    list.add("world");
    list.add("java");
    
    //创建集合迭代器
    ListIterator<String> lit = list.listIterator();
    
    //使用集合迭代器添加集合元素
    while (lit.hasNext()) {
        String s = lit.next();
        if (s.equals("world")) {
            lit.add("javascript");
        }
    }
    
    //使用集合迭代器删除集合元素
    while (lit.hasNext()) {
        String s = lit.next();
        if (s.equals("world")) {
            lit.remove();
        }
    }
    
    //使用集合迭代器修改集合元素
    while (lit.hasNext()) {
        String s = lit.next();
        if (s.equals("world")) {
            lit.remove();
            lit.add("javascript");
        }
    }
}
  1. 使用普通for循环来对集合元素进行操作

  • 思路一:正向操作 i++

public static void main(String[] args) {
    //创建集合对象
    List<String> list = new ArrayList<>();

    //添加元素
    list.add("hello");
    list.add("world");
    list.add("java");

    //普通for循环增加元素
    for (int i = 0; i < list.size(); i++) {
        String s = list.get(i);
        if (s.equals("java")) {
            list.add("javascript");
        }
    }

    //普通for循环删除元素
    for (int i = 0; i < list.size(); i++) {
        String s = list.get(i);
        if (s.equals("java")) {
            list.remove(s);
            i--;// 矫正位置
        }
    }

    //普通for循环修改元素
    for (int i = 0; i < list.size(); i++) {
        String s = list.get(i);
        if (s.equals("java")) {
            list.remove(s);
            list.add("javascript");
        }
    }
}
  • 思路二:反向操作 i--

public static void main(String[] args) {
    //创建集合对象
    List<String> list = new ArrayList<>();

    //添加元素
    list.add("hello");
    list.add("world");
    list.add("java");

    //普通for循环增加元素
    for (int i = list.size() - 1; i >= 0 ; i--) {
        String s = list.get(i);
        if (s.equals("java")) {
            list.add("javascript");
        }
    }

    //普通for循环删除元素
    for (int i = list.size() - 1; i >= 0 ; i--) {
        String s = list.get(i);
        if (s.equals("java")) {
            list.remove(s);
        }
    }

    //普通for循环修改元素
    for (int i = list.size() - 1; i >= 0 ; i--) {
        String s = list.get(i);
        if (s.equals("java")) {
            list.remove(s);
            list.add("javascript");
        }
    }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java集合框架中,如果多个线程同时对同一个集合进行修改操作,就有可能会引发并发修改异常(ConcurrentModificationException)。这个异常通常在使用迭代器遍历集合的过程中出现。 当一个线程正在使用迭代器遍历集合时,如果其他线程对集合进行了结构性修改(比如添加、删除元素),就会导致迭代器的fail-fast机制抛出并发修改异常。这是因为迭代器在遍历过程中会通过内部的modCount字段记录集合结构修改的次数,一旦发现结构修改次数与迭代器创建时不一致,就会抛出并发修改异常。 以下是一个可能引发并发修改异常的例子: ```java List<String> list = new ArrayList<>(); list.add("元素1"); list.add("元素2"); list.add("元素3"); Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String element = iterator.next(); if (element.equals("元素2")) { list.remove(element); // 并发修改集合 } } ``` 在上述代码中,一个线程正在使用迭代器遍历集合,另一个线程在遍历过程中删除了一个元素,导致并发修改异常。 为了避免并发修改异常,可以采取以下措施: - 使用线程安全的集合类,如`ConcurrentHashMap`、`CopyOnWriteArrayList`等。 - 在多线程环境下,对需要修改集合的操作进行同步,确保只有一个线程在修改集合。 - 在使用迭代器遍历集合时,不要同时进行修改操作,可以使用迭代器的remove()方法进行删除操作。 希望能够解答你的问题!如果还有任何疑问,请随时提出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值