You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同步方法中调用ArrayList.clear()仍触发ConcurrentModificationException原因排查

为啥加了synchronized还会遇到ConcurrentModificationException?

别着急,这个问题其实挺常见的,我来给你拆解下核心原因:

1. 同步方法只保护自身代码块,其他非同步的ArrayList访问没被覆盖

你给方法加了synchronized,只能保证同一时间只有一个线程执行这个方法里的代码,但如果还有其他线程在别的地方(比如另一个没加锁的方法、或者直接在方法外)对同一个ArrayList做这些操作:

  • 迭代遍历(比如用for-each循环、显式调用iterator())
  • 新增/删除元素(包括add()、remove())
    这些操作没有被同一个锁保护的话,就会和你的同步clear()操作产生并发冲突,触发ArrayList的快速失败机制,抛出ConcurrentModificationException。

举个直白的例子:线程A在执行你的同步clear()方法,同时线程B在另一个没加锁的方法里用for-each遍历这个ArrayList,这时候就会直接抛异常——因为synchronized只管自己的方法,管不到线程B的遍历操作。

2. 同步方法内部如果有迭代+修改的操作,单线程都能触发异常

哪怕是在你的同步方法里,如果先对ArrayList做了迭代(比如for (Object obj : list)),然后紧接着调用clear(),哪怕是同一个线程执行,也会抛出这个异常!因为ArrayList的迭代器是快速失败的,它会维护一个修改计数,迭代过程中如果集合被修改(包括clear()),就会立刻检测到并抛异常,这个和多线程没关系,是ArrayList本身的迭代特性。

比如这种代码,哪怕单线程跑都会炸:

synchronized void myMethod() {
    for (Object item : arrayList) {
        // 做点什么
    }
    arrayList.clear(); // 这里会触发迭代器的修改检测,抛ConcurrentModificationException
}

3. 锁的对象不统一,导致互斥失效

还有一种可能:你加synchronized的方法所在的对象,和其他线程操作ArrayList时用的锁不是同一个。比如你的ArrayList是类的成员变量,但其他线程操作它时,用的是另一个锁对象,那你的同步方法锁就起不到互斥作用。

比如这种情况:

public class MyClass {
    private ArrayList<Object> list = new ArrayList<>();

    // 这个方法锁的是MyClass实例
    synchronized void clearList() {
        list.clear();
    }

    // 其他地方的代码,锁的是list本身
    void anotherMethod() {
        synchronized (list) {
            list.add(new Object());
        }
    }
}

两个方法的锁不是同一个,还是会有并发冲突。

实用解决思路

给你几个靠谱的方案:

  • 把所有访问这个ArrayList的操作(遍历、修改、clear)都用同一个锁保护起来:要么都用synchronized方法(锁同一个对象),要么都显式锁ArrayList本身:synchronized(arrayList) { ... }
  • 换成线程安全的集合类:比如CopyOnWriteArrayList,它的迭代器基于快照,不会因为并发修改抛异常;或者用Collections.synchronizedList()包装你的ArrayList,但要注意遍历的时候还是得手动加锁
  • 如果在同步方法里需要迭代+修改,别用普通迭代器:改用ListIterator的remove()方法,或者先把元素复制到临时集合再迭代,避免在迭代过程中修改原集合

内容的提问来源于stack exchange,提问作者Tirafesi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:03:12