Николай Семенов Asked:2022-02-17 17:31:50 +0800 CST2022-02-17 17:31:50 +0800 CST 2022-02-17 17:31:50 +0800 CST java中的ConcurrentModificationException [重复] 772 我试图在互联网上找到文章,但基本上,他们都在谈论如何处理它。我想了解它是什么、在什么情况下发生、如何避免它等的基本知识。 java 1 个回答 Voted Best Answer Pak Uula 2022-02-17T22:25:18+08:002022-02-17T22:25:18+08:00 一段代码胜过一千多字…… 如果您对发生的情况感兴趣,请查看源代码。例如java.util.ArrayList和java.util.AbstractList 简而言之,每个类型对象AbstractList都有一个 counter modCount。每次更改列表的操作,例如添加元素、删除元素、清除列表等,此计数器都会递增。 那些需要在操作执行过程中不改变列表的操作,例如操作equals,保存操作modCount开始前的值,在操作结束时必须与 的当前值进行比较modCount。如果值不匹配,则ConcurrentModificationException. 最简单的例子是计算哈希码: public int hashCode() { int expectedModCount = modCount; int hash = hashCodeRange(0, size); checkForComodification(expectedModCount); return hash; } 如果当前值不匹配,该方法checkForComodification将抛出异常。modCountexpectedModCount 在类的文本中搜索表达式modCount++- 您将找到对象状态发生变化的所有地方。在操作执行期间对象被认为是不可变的所有那些地方都包含对checkForComodification. 如何避免? 一种简单但昂贵的运行方式是将集合上的所有操作包装在RWLock. 一种复杂且不可靠的方法是通过静态分析器运行程序并查找竞争条件。如果它没有找到它,那就交叉手指,相信不会有碰撞:)
一段代码胜过一千多字……
如果您对发生的情况感兴趣,请查看源代码。例如java.util.ArrayList和java.util.AbstractList
简而言之,每个类型对象
AbstractList
都有一个 countermodCount
。每次更改列表的操作,例如添加元素、删除元素、清除列表等,此计数器都会递增。那些需要在操作执行过程中不改变列表的操作,例如操作
equals
,保存操作modCount
开始前的值,在操作结束时必须与 的当前值进行比较modCount
。如果值不匹配,则ConcurrentModificationException
.最简单的例子是计算哈希码:
如果当前值不匹配,该方法
checkForComodification
将抛出异常。modCount
expectedModCount
在类的文本中搜索表达式
modCount++
- 您将找到对象状态发生变化的所有地方。在操作执行期间对象被认为是不可变的所有那些地方都包含对checkForComodification
.如何避免?
一种简单但昂贵的运行方式是将集合上的所有操作包装在
RWLock
. 一种复杂且不可靠的方法是通过静态分析器运行程序并查找竞争条件。如果它没有找到它,那就交叉手指,相信不会有碰撞:)