我有以下出于某种原因抛出ConcurrentModificationException
的代码。当我在带有线程之一的断点的调试器中运行它时抛出该异常,但显然不是这样。通过将断点(使用IntelliJ)设置为在线程级别挂起并检查每个类实例是否属于唯一线程,我已经确认该类不在线程之间共享。
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.access$300(EventAccumulator.java:20)
at com.abc.dept.featurex.aspectx.a.EventAccumulator$EventAccumulatorMaintenanceThread.run(EventAccumulator.java:99)
如果没有在线程之间共享类实例,为什么会抛出ConcurrentModificationException
?假设调试模式使用的是IDE中未报告的后台线程(即通过某种优化),那么在非调试模式(即生产环境)中使用这种方法是否安全?
答案 0 :(得分:0)
不,该类别几乎肯定不能在生产中使用。 调试器通常不会更改集合的内容。这就是这里发生的事情。在您遍历countsList时,其内容已更改。
尝试使用调试器或日志查找修改的源。也许您想在ArrayDequeue的某些方法中设置断点或重写断点并在其中放置一些日志。