ArrayList<A> objects = new ArrayList<A>;objects.add(new A(1));
objects.add(new A(2));
objects.add(new A(3));
objects.add(new A(4));
for(A object : objects) {
if (object.equals(A(1))) {
objects.remove(object);
}
}
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:782)
at java.util.ArrayList$Itr.next(ArrayList.java:754)
at HelloWorld.main(HelloWorld.java:12)
exception 이름을 보면 다중 thread 를 사용하거나 할 때 생길 법한데, 왜 나올까?
결론부터 말하자면, iterating 을 하는 와중에 remove() 를 했기 때문이다.
위와 같이 사용한 for 구문을 foreach 구문이라고도 하는데, foreach 구문은 내부적으로 iterator 를 사용한다. 때문에, 위의 for 문은,
for(Iterator iterator = objects.iterator(); iterator.hasNext();) {
A object = (A)iterator.next();
....
와 동일하다.
그런데, iterator 는 next() 또는 remove() 메소드가 호출될 때 현시점의 collection 수정 횟수와 생성 시점의 collection 수정 횟수를 비교해보고, 다르다면 ConcurrentModificationException 을 뱉는다.
문제는, ArrayList 의 remove() 메소드는 collection 수정 횟수를 하나 증가시킨다.
때문에, objects.remove() 가 수행된 다음 loop 의 iterator.next() 호출 시에, collection 수정 횟수가 맞지 않아 ConcurrentModificationException 이 발생한다.
결국, iterator 를 이용한 순회중 remove 를 할 것이라면 바로 break 를 해서 루프를 빠져나오거나, foreach 구문을 쓰지 않는 게 좋겠다.
참고 사이트 : http://suein1209.tistory.com/323