2012-05-26 4 views
2

я был в середине сделать игру мой последний, когда я заметил, что я случайно получить исключение, когда я называю repaint();является java.util.ConcurrentModificationException большой проблемой, в этом случае

Причиной всего этого было то, что разные объекты обновлялись в разное время и имели свои собственные Thread, чтобы обновить себя. Иногда сущность обновлялась, пока она окрашивается. Линия рисования работает примерно в 60-100 FPS, а объекты обновляются примерно раз в 300 мс.

Игра не прекращается или не имеет других проблем, связанных с этим.

Я знаю, что это плохая идея игнорировать его, но есть ли что-нибудь еще, что я могу сделать? Есть несколько потоков - единственное решение, которое я мог придумать, чтобы заставить игру работать.

Спасибо за чтение!

Редактировать: проблема возникает, когда я пытаюсь удалить объект, пока я рисую; оба используют один и тот же список.

+0

Трудно сказать, есть ли что-то еще, что вы можете сделать, если не укажете нам свой код. – Jeffrey

+0

. Мне пришлось бы поднять весь проект, если бы мне пришлось использовать код, который имел смысл. Слишком много классов, слишком долго. – imbuedHope

ответ

6

A ConcurrentModificationException не имеет ничего общего с многопоточным (хотя может быть задействовано несколько потоков). Это происходит, когда вы выполняете итерирование по коллекции (например, List), в то время как элементы добавляются или удаляются из коллекции с помощью других методов, отличных от метода Iterator.remove().

Это может произойти на другой теме, но это может быть одна и та же тема. Например, этот фрагмент кода будет также бросить ConcurrentModificationException:

Iterator iter = someList.iterator(); 
while(iter.hasNext()) { 
    Object item = iter.next(); 
    someList.remove(item); 
} 

Если вместо iter.remove() была вызвана ошибка не произошло бы.

способов избежать этого:

  1. Сделайте копию списка, прежде чем итерация над ним
  2. использовать только remove() метод итератора
  3. Используйте что-то вроде CopyOnWriteArrayList который избежать этой ошибки на за счет создания копии внутреннего массива при каждом изменении.
+0

Хотя в этом конкретном примере вы обычно используете метод 'remove()' итератора вместо списка. Но да, CME означает, что коллекция изменилась в какой-то момент между созданием итераторов и вызовом 'next()'. – Wormbo

+0

Я вижу. Затем это происходит, когда я пытаюсь удалить объект при рисовании. Проблема в том, что сама ошибка несовместима, поэтому мне сложно думать о решении. – imbuedHope

+0

@Wormbo. Пример должен был проиллюстрировать проблему, а не правильный способ сделать это :) –

1

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

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

Тот факт, что вы разрешаете двум потокам получать доступ к одному и тому же потокобезопасному списку одновременно, показывает, что ваш код неисправен , Это просто некорректно и обязательно должно быть исправлено.

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

+0

О, многопоточность не испортит список, содержащий блоки обновления. Я следил за проблемами синхронизации; мои потоки красок и события на клавиатуре были одновременными, что и вызвало эту проблему. Спасибо хоть! – imbuedHope

Смежные вопросы