Notice
Recent Posts
Recent Comments
Link
SeouliteLab
[Java/자바] ConcurrentModificationException 발생 및 해결 방법 본문
ConcurrentModificationException이란?
Java에서는 여러 스레드가 동시에 컬렉션을 수정할 때 ConcurrentModificationException이 발생할 수 있습니다. 이는 컬렉션을 반복하는 도중에 해당 컬렉션의 구조가 변경되었을 때 발생합니다. 이 문제를 해결하기 위해서는 몇 가지 방법이 있습니다.
ConcurrentModificationException 발생 원인
ConcurrentModificationException은 일반적으로 다음과 같은 상황에서 발생합니다.
- 반복자(iterator)를 사용하여 컬렉션을 순회하는 중에 컬렉션을 수정할 경우
- 여러 스레드가 동시에 컬렉션을 수정할 경우
ConcurrentModificationException 해결 방법
ConcurrentModificationException을 해결하는 방법은 다양하지만, 주로 다음과 같은 방법을 사용합니다.
- Enhanced For Loop 사용 시 ConcurrentModificationException 방지
- Iterator 사용 시 ConcurrentModificationException 방지
- Synchronized 또는 Concurrent 컬렉션 사용
Enhanced For Loop 사용 시 ConcurrentModificationException 방지
Enhanced For Loop를 사용하여 컬렉션을 반복하는 경우, 컬렉션을 직접 수정하지 않는 것이 좋습니다. 대신 반복 중에 수정이 필요한 경우 임시 컬렉션을 만들어 수정을 수행하는 것이 좋습니다.
List list = new ArrayList<>();
list.add("one");
list.add("two");
// 잘못된 예제
for (String s : list) {
if (s.equals("two")) {
list.remove(s); // ConcurrentModificationException 발생
}
}
// 올바른 예제
List tempList = new ArrayList<>();
for (String s : list) {
if (!s.equals("two")) {
tempList.add(s);
}
}
list = tempList;
Iterator 사용 시 ConcurrentModificationException 방지
Iterator를 사용하여 컬렉션을 순회하는 경우에도 동일한 원칙이 적용됩니다. 반복 중에 컬렉션을 직접 수정하는 것은 피해야 합니다.
List list = new ArrayList<>();
list.add("one");
list.add("two");
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
String s = iterator.next();
if (s.equals("two")) {
iterator.remove(); // ConcurrentModificationException 방지
}
}
Synchronized 또는 Concurrent 컬렉션 사용
스레드 안전한 Synchronized 컬렉션이나 Concurrent 컬렉션을 사용하는 것도 ConcurrentModificationException을 방지하는 좋은 방법입니다.
Map synchronizedMap = Collections.synchronizedMap(new HashMap<>());
ConcurrentModificationException 해결 예제
아래는 ConcurrentModificationException을 해결하는 다양한 방법을 보여주는 예제 코드입니다.
import java.util.*;
public class ConcurrentModificationExample {
public static void main(String[] args) {
// 예제 1: Enhanced For Loop를 사용하여 컬렉션 순회
List list = new ArrayList<>(Arrays.asList("one", "two", "three"));
List tempList = new ArrayList<>();
for (String s : list) {
if (!s.equals("two")) {
tempList.add(s);
}
}
list = tempList;
System.out.println("After removing 'two' using Enhanced For Loop: " + list);
// 예제 2: Iterator를 사용하여 컬렉션 순회
List list2 = new ArrayList<>(Arrays.asList("one", "two", "three"));
Iterator iterator = list2.iterator();
while (
iterator.hasNext()) {
String s = iterator.next();
if (s.equals("two")) {
iterator.remove();
}
}
System.out.println("After removing 'two' using Iterator: " + list2);
// 예제 3: Synchronized 컬렉션 사용
Map synchronizedMap = Collections.synchronizedMap(new HashMap<>());
synchronizedMap.put("key1", "value1");
synchronizedMap.put("key2", "value2");
System.out.println("Synchronized Map: " + synchronizedMap);
}
}
'프로그래밍' 카테고리의 다른 글
[Java/자바] JUnit - @Before와 @BeforeClass의 차이점 (0) | 2024.03.09 |
---|---|
[Java/자바] JUnit - @After와 @AfterClass의 차이점 (0) | 2024.03.09 |
[Java/자바] 두 개의 Map 합치기 (merge, putAll) (0) | 2024.03.09 |
[Java/자바] Stream의 flatMap() 메서드 사용 방법 (0) | 2024.03.09 |
[Java/자바] Stream의 map() 메서드 사용 방법 (0) | 2024.03.09 |