Почему ConcurrentModificationException брошен и как отладить его

Я использую a Collection (a HashMap используемый косвенно JPA, это так происходит), но по-видимому случайным образом код бросает a ConcurrentModificationException. Что вызывает его и как я решаю эту проблему? При помощи некоторой синхронизации, возможно?

Вот полное отслеживание стека:

Exception in thread "pool-1-thread-1" java.util.ConcurrentModificationException
        at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
        at java.util.HashMap$ValueIterator.next(Unknown Source)
        at org.hibernate.collection.AbstractPersistentCollection$IteratorProxy.next(AbstractPersistentCollection.java:555)
        at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:296)
        at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:242)
        at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:219)
        at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
        at org.hibernate.engine.Cascade.cascade(Cascade.java:130)
116
задан Raedwald 16 September 2019 в 15:19
поделиться

5 ответов

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

Iterator it = map.entrySet().iterator();
while (it.hasNext())
{
   Entry item = it.next();
   map.remove(item.getKey());
}

Это бросит ConcurrentModificationException, когда it.hasNext () назовут во второй раз.

корректный подход был бы

   Iterator it = map.entrySet().iterator();
   while (it.hasNext())
   {
      Entry item = it.next();
      it.remove();
   }

Предположение, что этот итератор поддерживает удаление () операция.

247
ответ дан Bert F 24 November 2019 в 02:12
поделиться

Попытайтесь использовать ConcurrentHashMap вместо плоскости HashMap

65
ответ дан Chochos 24 November 2019 в 02:12
поделиться

Это меньше походит на проблему синхронизации Java и больше как проблема блокировки базы данных.

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

Мог быть то, что уровень изоляции должен быть выше. При разрешении "грязных чтений" возможно, необходимо натолкнуться до сериализуемого.

2
ответ дан duffymo 24 November 2019 в 02:12
поделиться

Попробуйте или CopyOnWriteArrayList или CopyOnWriteArraySet в зависимости от того, что Вы пытаетесь сделать.

0
ответ дан Javamann 24 November 2019 в 02:12
поделиться

В Java 8 можно использовать лямбда-выражение:

map.keySet().removeIf(key -> key condition);
1
ответ дан 24 November 2019 в 02:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: