ConcurrentModificationException выдается при запуске в отладчике - PullRequest
0 голосов
/ 03 декабря 2018

У меня есть следующий код, который выбрасывает 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?

1 Ответ

0 голосов
/ 03 декабря 2018

Нет, этот класс почти наверняка небезопасен для использования в производстве.Отладчики обычно не изменяют содержимое коллекции.И вот что здесь произошло.Содержимое countsList было изменено во время итерации по нему.

Попробуйте найти источник модификации с помощью отладчика или журнала.Может быть, вы хотите установить точки останова в некоторых методах ArrayDequeue или переопределить его и поместить в него какой-нибудь журнал.

...