问题
map删除元素时,报错java.util.ConcurrentModificationException
源码
public void remove() {
if (lastRet == -1)
throw new IllegalStateException();
checkForComodification();
try {
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
原因
modCount,每次对集合进行修改(增添 / 删除……)时都会modCount++。
expectedModCount,对ArrayList修改次数的预期的数值,初始化与modCount相等。但如果接下来如果集合进行修改modCount改变,就会造成expectedModCount!=modCount,此时就会抛出java.util.ConcurrentModificationException异常。
这样设计主要是为了防止多线程问题。
解决
使用iterator进行删除
Iterator<String> iterator = oneMap.keySet().iterator();
while(iterator.hasNext()){
String str = iterator.next();
if( str.equals("相同的字符串") )
{
iter.remove();
}
}
加锁
迭代前加锁
使用线程安全的数据结构
- ConcurrentHashMap
- CopyOnWriteArrayList
- ...
参考

本文探讨了在Java中从Map中并发删除元素时遇到的java.util.ConcurrentModificationException异常。通过分析源码,揭示了异常产生的根本原因,并提供了三种解决方案:使用迭代器删除、迭代前加锁及采用线程安全的数据结构。
2326

被折叠的 条评论
为什么被折叠?



