ConcurrentModificationException как исправить

Grind

Заблокирован
Местный
Сообщения
457
Розыгрыши
0
Реакции
111
Репутация
-96
Баллы
163
Обратите внимание, что данный пользователь заблокирован! Не совершайте с ним никаких сделок! Перейдите в его профиль, чтобы узнать причину блокировки.
Я постараюсь доступным языком рассказать об этой ошибке, её природе и способах устранения.

Исключение (ошибка) ConcurrentModificationException случается когда коллекция (или массив) изменяется одновеременно с работой по ней итератором, любым средством кроме самого итератора. Грубо говоря, вы хотите вставить в массив элемент, в то время как из массива делается выборка элемента.

Для предотвращения (исправления) такой ситуации, в тех колекциях/масивах, где такая ситуация может возникать, необходимо использовать синхронизированную (она же потокобезопасная) коллекцию.

Потокобезопасные коллекции/массивы всегда будут более затратны по времени и использованию системных ресурсов, поэтому старайтесь избегать таких ситуаций. Однако если другое решение не очевидно или неоправдано, то следует для начала опеределить, требуется ли вам синхронизация чтения/записи или только записи. 1ый вариант более ресурсоемкий чем 2ой.

Чаще всего в работе с исходным кодом вы будете встречаться с массивами List/ArrayList, в большинстве случаев рассинхрон будет происходить на операциях ввода данных, поэтому мы рассмотрим такой потобезопасный вариант массива как CopyOnWriteArrayList.

При каждой операции записи CopyOnWriteArrayList будет создавать новую копию ArrayList, тем самым не мешая одновременно чтению данных из этой коллекции.
 
Последние выданные очки репутации:
kekess 17 Баллы неужели понял )))), молодец, быстро учишся
kick 15 Баллы

kekess

Интересующийся
Местный
Сообщения
74
Розыгрыши
0
Реакции
236
Репутация
178
Баллы
219
:Shock1: неужели понял )))), молодец, быстро учишься
 

Grind

Заблокирован
Местный
Сообщения
457
Розыгрыши
0
Реакции
111
Репутация
-96
Баллы
163
Обратите внимание, что данный пользователь заблокирован! Не совершайте с ним никаких сделок! Перейдите в его профиль, чтобы узнать причину блокировки.
:Shock1: неужели понял )))), молодец, быстро учишься
я не учусь, я практикую, и затруднений в понимании этого не испытывал, будут вопросы обращайся нубас -:D
 

kekess

Интересующийся
Местный
Сообщения
74
Розыгрыши
0
Реакции
236
Репутация
178
Баллы
219
-:D практик хренов :rofl1:
 

GenCloud

Последний из атеистов
Open Source
Contributor
Сообщения
431
Розыгрыши
0
Реакции
516
Репутация
2 127
Баллы
757
Боже, для кого ты это обьясняешь??? Для юниоров, и то они знают коллекции, или для кого?
 
Последнее редактирование модератором:

Grind

Заблокирован
Местный
Сообщения
457
Розыгрыши
0
Реакции
111
Репутация
-96
Баллы
163
Обратите внимание, что данный пользователь заблокирован! Не совершайте с ним никаких сделок! Перейдите в его профиль, чтобы узнать причину блокировки.
Боже, для кого ты это обьясняешь??? Для юниоров, и то они знают коллекции, или для кого?
наверно для таких нубасов как ты, которые пропускали математику в 5ом классе и считают что при деление 555 по модулю на 15 мы получим 8 в остатке -:D
пруф https://mmo-develop.ru/index.php?threads/Оператор-деления-по-модулю.768/poll/results&poll_response_id=47

для тебя другие задачи у меня есть https://mmo-develop.ru/index.php?threads/Тернарный-оператор-задача.772/#post-8375
 
Последнее редактирование модератором:

Grind

Заблокирован
Местный
Сообщения
457
Розыгрыши
0
Реакции
111
Репутация
-96
Баллы
163
Обратите внимание, что данный пользователь заблокирован! Не совершайте с ним никаких сделок! Перейдите в его профиль, чтобы узнать причину блокировки.

L2CCCP

Работник недели xD
Партнер
Сообщения
464
Розыгрыши
0
Реакции
940
Репутация
1 932
Баллы
916
Боже бл**ь, для кого ты это обьясняешь??? Для юниоров, и то они знают коллекции, или для кого?
Уверяю, не все знают коллекции, многие знают только List,ArrayList,Map,HashMap, а бывает и их не знают :D
 
Последние выданные очки репутации:
kick 15 Баллы

L2CCCP

Работник недели xD
Партнер
Сообщения
464
Розыгрыши
0
Реакции
940
Репутация
1 932
Баллы
916
Уверен и того многие не знают, а также EnumMap, LinkedList, PriorityQueue, SortedMap итд туда же, таких коллекции десятки, а если пройтись по форкам то и вовсе сотни
Тема бесконечна для обсуждения :-)
 

Daan Raven

Свой человек
Проверенный
Сообщения
799
Розыгрыши
0
Реакции
351
Репутация
886
Баллы
469
Уверен и того многие не знают, а также EnumMap, LinkedList, PriorityQueue, SortedMap итд туда же, таких коллекции десятки, а если пройтись по форкам то и вовсе сотни
Тема бесконечна для обсуждения :-)
Тогда уж взять интерфейсы, которые эти все коллекции реализуют - Set, Map, List, Queue :-) Ну или вовсе Collection :D

Тема не имеет смысла, так как описание этого эксепшна есть в офф.документации.
 

zcxv

Antihero
Проверенный
Сообщения
490
Розыгрыши
0
Реакции
1 343
Репутация
812
Баллы
100
Стоит упомянуть, что использование коллекций основанных на массивах - очень нежелательно при высокой частоте добавления и удаления элементов, т.к. в CopyOnWrite на каждую такую операцию массив ресайзится. Если такая коллекция долгоживущая, то элементы ее массива попадут в олдген и с большой вероятностью вообще никогда не очистятся (ну опять же, все зависит от настройки JVM, но если говорить конкретно о l2j, то я видел fullgc лишь несколько раз, да и то, от жесткого недостатка памяти; плюс стоит помнить, что fullgc - нежелательный гость).
Вспоминаем, что все коллекции основанные на массивах имеют RandomAccess, что означает, то что их итерация методом итераторов (уж извините за косноязычие) - плохо и таких людей надо шлепать по попе. В нормальном случае такие коллекции итерируются методом:
Код:
for(int i = 0; i < collection.size(); i++) {
  E element = collection.get(i);
  ...
}
Если мы хотим использовать коллекцию в случаях, когда у нас частые вызовы на удаление/запись, то лучше использовать вещи основанные на нодах, а-ля LinkedBlockingDeque/LinkedBlockingQueue/LinkedList/..., ну и конечно же придется делать свою имплементацию таких вещей и подключать туда кеширование нод, чтобы не напрягать GC.
 

Mangol

Участник
Пользователь
Сообщения
14
Розыгрыши
0
Реакции
2
Репутация
964
Баллы
0

Grind

Заблокирован
Местный
Сообщения
457
Розыгрыши
0
Реакции
111
Репутация
-96
Баллы
163
Обратите внимание, что данный пользователь заблокирован! Не совершайте с ним никаких сделок! Перейдите в его профиль, чтобы узнать причину блокировки.
Стоит упомянуть, что использование коллекций основанных на массивах - очень нежелательно при высокой частоте добавления и удаления элементов, т.к. в CopyOnWrite на каждую такую операцию массив ресайзится. Если такая коллекция долгоживущая, то элементы ее массива попадут в олдген и с большой вероятностью вообще никогда не очистятся (ну опять же, все зависит от настройки JVM, но если говорить конкретно о l2j, то я видел fullgc лишь несколько раз, да и то, от жесткого недостатка памяти; плюс стоит помнить, что fullgc - нежелательный гость).
Вспоминаем, что все коллекции основанные на массивах имеют RandomAccess, что означает, то что их итерация методом итераторов (уж извините за косноязычие) - плохо и таких людей надо шлепать по попе. В нормальном случае такие коллекции итерируются методом:
Код:
for(int i = 0; i < collection.size(); i++) {
  E element = collection.get(i);
  ...
}
Если мы хотим использовать коллекцию в случаях, когда у нас частые вызовы на удаление/запись, то лучше использовать вещи основанные на нодах, а-ля LinkedBlockingDeque/LinkedBlockingQueue/LinkedList/..., ну и конечно же придется делать свою имплементацию таких вещей и подключать туда кеширование нод, чтобы не напрягать GC.
я практикую в таких случаях LinkedList, еще я практикую очищение (clear) коллекции/массива после завершнения работы с ним.
 
Сверху Снизу