Java에서 ConcurrentModificationException은 컬렉션을 동시에 수정하려고 할 때 발생합니다. 이 예외는 다른 스레드나 iterator가 컬렉션을 수정하는 동안, 현재 스레드에서 해당 컬렉션을 수정하려고 할 때 발생합니다.
예를 들어, 다음과 같은 코드에서는 ConcurrentModificationException이 발생할 수 있습니다.
List<Integer> numbers = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
for (Integer number : numbers) {
if (number == 3) {
numbers.remove(number);
}
}
이 코드에서는 numbers 리스트에서 iterator를 통해 요소를 순회하면서, 요소가 3인 경우 해당 요소를 삭제하려고 합니다. 그러나, ArrayList는 내부적으로 배열을 사용하고, 요소를 삭제하면 배열의 크기가 변경될 수 있습니다. 이때, 다른 스레드나 iterator가 컬렉션을 동시에 수정하려고 하면 ConcurrentModificationException이발생할 수 있습니다.
해결 방법은 다음과 같습니다.
1. iterator를 사용하여 컬렉션을 수정하기 컬렉션을 수정할 때는 iterator를 사용하여 컬렉션을 수정해야 합니다. iterator는 내부적으로 컬렉션을 변경하는 것을 방지하기 때문에, 이 방법으로는 ConcurrentModificationException을 피할 수 있습니다.
List<Integer> numbers = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
Iterator<Integer> iterator = numbers.iterator();
while (iterator.hasNext()) {
Integer number = iterator.next();
if (number == 3) {
iterator.remove();
}
}
2. 동기화된 컬렉션 사용하기 Java는 동기화된 컬렉션을 제공합니다. 이 컬렉션은 여러 스레드에서 동시에 접근할 수 있도록 설계되어 있으므로, 여러 스레드에서 컬렉션을 수정할 때 ConcurrentModificationException을 방지할 수 있습니다.
List<Integer> numbers = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
List<Integer> synchronizedNumbers = Collections.synchronizedList(numbers);
3. 스트림을 사용하여 컬렉션을 수정하기 Java 8부터는 스트림을 사용하여 컬렉션을 수정할 수 있습니다. 이 경우, ConcurrentModificationException을 방지할 수 있습니다.
List<Integer> numbers = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
numbers.removeIf(number -> number == 3);
위 코드에서는 removeIf 메소드를 사용하여 컬렉션을 수정합니다. 이 메소드는 요소를 삭제하기 위해 내부적으로 iterator를 사용합니다.
'Programming > Java' 카테고리의 다른 글
map과 list 중 검색 속도가 빠른 것은? (0) | 2023.02.23 |
---|---|
HashMap과 시간 복잡도 (0) | 2023.02.23 |
Checked Exception과 Unchecked Exception (0) | 2023.02.23 |
String, String Buffer, String Builder (0) | 2023.02.22 |
Final, Finally, Finalize 비교 (0) | 2023.02.22 |