在调试器中 运行 时抛出 ConcurrentModificationException

ConcurrentModificationException thrown when running in debugger

我有以下代码由于某种原因抛出 ConcurrentModificationException。当我 运行 在其中一个线程中设置断点的调试器中抛出它时,但显然不是这样。通过将断点(使用 IntelliJ)设置为在线程级别挂起并检查每个 class 实例是否属于唯一线程,我已确认所讨论的 class 未在线程之间共享。

public class EventAccumulator implements Observer {
  private AtomicInteger inputCount = new AtomicInteger();

  private ArrayDeque<Integer> countsList;

  ...

  private void updatePeriodCount() {
    countsList.addFirst(inputCount.get());
    inputCount.set(0);
    while (countsList.size() >= 30) {
      countsList.pollLast();
    }
    int finalCount = 0;
    for (int count : countsList) { //<--ConcurrentModificationException
      finalCount += count;
    }
    ...
  }

异常:

Exception in thread "Thread-23" java.util.ConcurrentModificationException
    at java.util.ArrayDeque$DeqIterator.next(ArrayDeque.java:648)
    at com.abc.dept.featurex.aspectx.a.EventAccumulator.updatePeriodCount(EventAccumulator.java:64)
    at com.abc.dept.featurex.aspectx.a.EventAccumulator.access0(EventAccumulator.java:20)
    at com.abc.dept.featurex.aspectx.a.EventAccumulator$EventAccumulatorMaintenanceThread.run(EventAccumulator.java:99)

如果 class 实例不在线程之间共享,为什么会抛出 ConcurrentModificationException?假设调试模式正在使用未在 IDE 中报告的后台线程(即通过某些优化),这在非调试模式(即生产)中使用是否安全?

不,这个 class 在生产中使用几乎肯定是不安全的。 调试器通常不会更改集合的内容。这就是这里发生的事情。 countsList 的内容在您对其进行迭代时发生了变化。

尝试通过调试器或日志找到修改源。也许您想在 ArrayDequeue 的某些方法中设置断点或覆盖它并在其中放置一些日志。