2013-07-01 5 views
-2

Я не понимаю, почему этот метод вызывает исключение:Странное поведение ConcurrentModificationException

public void add(Object obj){ 
    gameObjects.add(obj); //here the exception happens 
} 

... в то время как это один не делает:

public void add(Object obj){ 
    gameObjects.add(obj); // no exception actually happens here 
    gameObjects.remove(obj); 
} 

Почему это происходит, учитывая, что это это исключение времени выполнения?

Исключение:

Exception in thread "Thread-0" java.util.ConcurrentModificationException 
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source) 
    at java.util.ArrayList$Itr.next(Unknown Source) 
    at threads.Main.tick(Main.java:181) 
    at threads.Main.run(Main.java:104) 

Метод вызывается для метода клеща внутри объекта.

gameObjects не равно нулю:

List<Object> gameObjects = new ArrayList<Object>(128); 
+9

Это не достаточно информации. Во-первых, что такое исключение. Кроме того, каков контекст этих вызовов? Кто называет код и как? –

+0

Какой тип gameObjects? – Cemafor

+0

Что такое 'gameObjects'? Это нулевое значение? – NINCOMPOOP

ответ

3

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

Если вы хотите добавить его, вы должны сделать это, используя итератор.

2

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

Обратите внимание, что это не метод add, который проверяет наличие ConcurrentModificationException; скорее, коллекция проверяется на любые модификации в конце каждой итерации цикла.

+0

Но вызов метода «Добавить» не может знать о следующем вызове метода «Удалить», поэтому он не может рассуждать о чистом изменении и не решает исключить исключение. Я что-то упускаю? –

+1

@ TheodorosChatzigiannakis Метод 'add' не проверяет наличие параллельной модификации. – arshajii

+0

О да, вы правы, я просто видел трассировку стека. Все равно глупо. –

0

согласно doc

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

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

0

Вы не можете изменить одинаково object при обходе.

JavaDoc Сэя

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

Для получения более подробной информации следуйте по этим ссылкам. Они могут помочь вам учиться.

Concurrent Modification exception http://docs.oracle.com/javase/6/docs/api/java/util/ConcurrentModificationException.html