Страницы

Поиск по вопросам

суббота, 28 декабря 2019 г.

Как обработать исключение java.util.ConcurrentModificationException?

#java


Есть код: ссылка на github. В ходе выполнения выбрасывается исключение Exception
in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException 
Знающие люди подскажите как побороть проблему. Заранее спасибо)
    


Ответы

Ответ 1



Его не надо обрабатывать. Это исключение значит, что вы в своем коде удаляете элемент напрямую из коллекции во время использования итератора. Т.к. в этом случае появляется неопределенность, откуда итератор должен продолжать и какие последующие элементы должен пройти, выбрасываетс исключение. Для корректного изменения сущности используйте методы итератора, например, iterator.remove().

Ответ 2



Например, можно поставить блокировку перед началом модификации ArrayList и снять блокировку после завершения модификации. Используете неконкурентную структуру данных ArrayList. Такая сруктура данных будет корректно работать если поток один. while (i.hasNext()) { synchronized (i) { Enemy e = i.next(); if (e.x >= 1600 || e.x <= -1600) { i.remove(); } else { e.move(); // поправить позже g.drawImage(e.img, e.x, e.y, null); } } } В этом коде блокировка снимается позже завершения модификации. Можно код переписать так: while (i.hasNext()) { boolean isDrawImage = false; synchronized (i) { Enemy e = i.next(); if (e.x >= 1600 || e.x <= -1600) { i.remove(); } else { e.move(); // поправить позже isDrawImage = true; } } if (isDrawImage) g.drawImage(e.img, e.x, e.y, null); }

Ответ 3



В дополнение к ответу etki привожу код для корректного удаления элемента коллекции внутри цикла итератора: Iterator i = strings.iterator(); while (i.hasNext()) { String value = i.next(); // должен быть вызван перед тем, как вызывается i.remove() // какой-то код i.remove(); // Элемент value был удалён из коллекции strings }

Комментариев нет:

Отправить комментарий