如何调试并发修改异常?

我遇到了 ConcurrentModificationException,通过观察它,我看不出它发生的原因;引发异常的区域和修改集合的所有位置都由

synchronized (this.locks.get(id)) {
  ...
} // locks is a HashMap<String, Object>;

我试图抓住讨厌的线程,但我所能钉(通过在异常中设置断点)是抛出线程拥有监视器,而另一个线程(程序中有两个线程)休眠。


我应该如何继续?当您遇到类似的线程问题时,您通常会做什么?


答案 1

它可能与同步块无关。在循环访问集合元素时修改集合时,通常会发生这种情况。ConcurrentModificationException

List<String> messages = ...;
for (String message : messages) {
    // Prone to ConcurrentModificationException
    messages.add("A COMPLETELY NEW MESSAGE");
}

答案 2

与之前的帖子类似,如果您删除条目,可能会遇到相同的问题。例如:

for(String message : messages) {
  if (condition(message))
     messages.remove(message);
}

另一个常见示例是清理地图。

可以使用迭代器显式解决此特定问题。

for(Iterator<String> iter = messages.iterator(); iter.hasNext();) {
   String message = iter.next();
   if (condition(message))
       iter.remove(); // doesn't cause a ConcurrentModificationException 
}

推荐