티스토리 뷰

이 Exception의 경우 주로 Collection객체를 loop로 다룰 때 발생하게 된다.

 

나의 경우 Queue를 Iterator를 통해 탐색할 때 발생하였다.

 

 

Iterator란?

: java에서 Collection에 저장되어있는 요소들을 읽어오는 표준화된 방법 중 하나이다.

Queue<Integer> q = new LinkedList<>();
q.add(1);
q.add(2);
q.add(3);

Iterator<Integer> iter = q.iterator();

//1. 반복문 안에서 단순히 요소 접근만 함
while(iter.hasNext()){
	System.out.println(iter.next());
}

iter = q.iterator();
//2. 반복문 안에서 타겟 리스트 객체를 수정함
while(iter.hasNext()){
	System.out.println(iter.next());
    q.remove(1);
}

이런 식으로 큐에 담긴 요소들을 하나씩 읽어서 출력할 수 있는 데 사용된다.

 

1번 반복문의 경우 단순히 요소에만 접근하여 아무런 문제가 없는 코드이지만 2번 반복문처럼 반복문 안에서 타깃 컬렉션 객체를 수정하는 경우에는 java.util.ConcurrentModificationException이 발생하게 된다.

 

 

 

Exception 발생 원인

: Iterator 인터페이스의 구조를 살펴보면 알 수 있다.

private class Itr implements Iterator<E> {
       ...
        int expectedModCount = modCount;
        ...
}

컬렉션은 Iterator를 생성할 때 내부 클래스인 Itr클래스로 생성하게 된다. iterator객체를 생성할 때 modCount는 지역변수로 할당된다. 

*modCount : 타깃 컬렉션에 변경사항이 생길 때마다 변경된 카운트(길이)를 기록하는 변수 

 

 

public E next() {
    checkForComodification();
    ...
}

final void checkForComodification() {
    if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
}

다음 요소를 가져오는 iter.next()를 호출하면 자신이 참조하고 있는 타깃 컬렉션에 변경사항이 있는지 체크하게 되고 여기서 카운트 변수인 modCount와 지역변수인 expectedModCount가 다를 경우 Exception을 발생시킨다. 

 

따라서 modCount가 조작되는 모든 메서드 (remove, add.. 등)를 반복문에서 함께 사용하여 타깃 컬렉션에 접근한다면 Exception이 발생한다.

 

즉, 반복문 내부에서 타깃 컬렉션의 길이가 변하게 되어 처음 참조한 카운트 변수와 같지 않기 때문에 발생하게 되는 것.

 

 

 

 

 

 

 

 

 

Iterator를 사용할 때만 발생하는지?

java 컬렉션 요소를 순차 접근할 때 비슷한 경우라면 발생한다고 보면 된다. 

ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
		
for(int i : list) {
	System.out.println(i);
	list.add(4);
}

 위와 같은 반복문의 경우도 내부적으로는 iterator인터페이스 객체를 통해 접근하는 것이므로 같은 Exception이 발생할 수 있다. 

 

 

 

 

결론적으로, 컬렉션 요소에 접근할 때에 반복문 안에서 타깃 객체를 변경하는 메서드를 사용하는 것에 주의하자!

 

 

 

 

 

+덧붙여 iterator로 접근하면 이렇게 인터페이스 객체를 생성하여 요소에 접근하므로 list의 size를 받아와서 반복문을 통해 요소 접근할 때보다 느리다. 따라서 list의 size를 받아 사용이 가능한 경우라면 이렇게 사용하는 게 iterator를 사용하는 것보다 빠르다.

 

 

 

 

 

참고사이트

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함