ConcurrentModificationException удаление элемента из итератора - PullRequest
0 голосов
/ 23 января 2019

Возникло исключение ConcurrentModificationException, удаляющее запись с карты, но я не вижу, что не так.

    Iterator<String> mapIterator = this.attributeMap.keySet().iterator();
    while (mapIterator.hasNext())
    {
        String attributeName = mapIterator.next();
        if (attributeName.matches(pattern))
        {
            mapIterator.remove();
        }
    }

Ответы [ 2 ]

0 голосов
/ 23 января 2019

В этом случае строка mapIterator.next () броски ConcurrentModificationException.

Причина этого:
Существует переменная int modCount, которая показывает, сколько раз размер списка был изменен, это значение используется при каждом вызове next() для проверки любых изменений в функции checkForComodification().
если mapIterator.next() обнаружит изменение в modCount во время итерации объекта, то будет выдано ConcurrentModificationException.

Чтобы избежать этого, следуйте приведенным ниже пунктам:

  1. Вы можете преобразовать список в массив, а затем выполнить итерацию по массиву. Этот подход хорошо работает для небольшого или среднего списка, но если список большой, это сильно повлияет на производительность.

  2. Вы можете заблокировать список во время итерации, поместив его в синхронизированный блок. Этот подход не рекомендуется, потому что он прекратит преимущества многопоточности.

  3. Если вы используете JDK1.5 или выше, вы можете использовать классы ConcurrentHashMap и CopyOnWriteArrayList. Это рекомендуемый подход.

0 голосов
/ 23 января 2019

Вы можете проверить это на некоторых деталях о CME: https://docs.oracle.com/javase/7/docs/api/java/util/ConcurrentModificationException.html

Это исключение может быть вызвано методами, которые обнаружили одновременную модификацию объекта, когда такая модификация недопустима. Например, как правило, один поток не может изменять коллекцию, пока другой поток итерирует по ней. В общем, результаты итерации в этих обстоятельствах не определены. Некоторые реализации Iterator (включая реализации всех реализаций коллекций общего назначения, предоставляемых JRE) могут выбрасывать это исключение, если обнаруживается такое поведение. Итераторы, которые делают это, известны как итераторы с быстрым отказом, так как они быстро и чисто терпят неудачу, а не рискуют произвольным, недетерминированным поведением в неопределенное время в будущем.

Вот некоторые решения, предоставленные Baeldung, связанные ниже:

  1. Непосредственное использование итератора
  2. Не удаляется во время итерации
  3. Использование removeIf ()
  4. Фильтрация с использованием потоков

Вы можете проверить его сайт для деталей для каждого решения, чтобы избежать CME: https://www.baeldung.com/java-concurrentmodificationexception

Надеюсь, это поможет.

...