개발기록
HashMap의 Thread-safety와 대안들 본문
Java의 HashMap은 멀티스레드 환경에서 안전하지 않습니다. 여러 스레드가 동시에 HashMap을 수정하면 예기치 않은 결과가 발생할 수 있습니다. 이 글에서는 HashMap의 Thread-safety 문제와 그 해결책에 대해 알아보겠습니다.
HashMap의 Thread-safety 문제
- 데이터 불일치: 여러 스레드가 동시에 데이터를 수정하면 일부 수정사항이 손실될 수 있습니다.
- 무한 루프: 특정 상황에서 여러 스레드의 동시 수정으로 인해 내부 링크드 리스트가 순환 구조가 되어 무한 루프에 빠질 수 있습니다.
- 예외 발생: ConcurrentModificationException과 같은 예외가 발생할 수 있습니다.
Thread-safe 대안들
1. Collections.synchronizedMap()
가장 간단한 방법으로, 기존 HashMap을 동기화된 Map으로 래핑합니다.
Map<String, Integer> syncMap = Collections.synchronizedMap(new HashMap<>());
장점:
- 사용이 간단함
- 모든 메서드가 동기화됨
단점:
- 성능이 상대적으로 낮음 (모든 작업이 동기화되므로)
- 복합 작업에 대한 원자성 보장이 어려움
2. ConcurrentHashMap
Java 5부터 도입된 ConcurrentHashMap은 동시성을 고려하여 설계되었습니다.
Map<String, Integer> concurrentMap = new ConcurrentHashMap<>();
장점:
- 높은 동시성과 성능
- 세분화된 락킹으로 인해 여러 스레드가 동시에 다른 세그먼트에 접근 가능
- 복합 연산을 위한 원자적 메서드 제공 (예: putIfAbsent, replace)
단점:
- 약간의 메모리 오버헤드
- 일부 시나리오에서는 완벽한 일관성을 보장하지 않음 (size() 메서드 등)
3. 명시적 동기화
synchronized 키워드를 사용하여 명시적으로 동기화할 수 있습니다.
public class ThreadSafeMap<K, V> {
private final Map<K, V> map = new HashMap<>();
public synchronized V put(K key, V value) {
return map.put(key, value);
}
public synchronized V get(K key) {
return map.get(key);
}
// 다른 메서드들도 유사하게 구현
}
장점:
- 완벽한 제어 가능
- 특정 상황에 맞춘 최적화 가능
단점:
- 구현이 복잡할 수 있음
- 잘못 구현 시 데드락 등의 문제 발생 가능
성능 비교
각 방식의 대략적인 성능 비교는 다음과 같습니다 (환경에 따라 다를 수 있음):
- HashMap (비동기): 가장 빠름
- ConcurrentHashMap: HashMap보다 약간 느림
- Collections.synchronizedMap(): ConcurrentHashMap보다 느림
- 명시적 동기화: 구현에 따라 다름, 일반적으로 가장 느림
사용 시 주의사항
- 적절한 방식 선택: 요구사항과 사용 패턴에 따라 적절한 방식을 선택하세요.
- 복합 연산 주의: get-then-put과 같은 복합 연산 시 동기화에 특별히 주의해야 합니다.
- 반복자 사용: 동기화된 맵의 반복자 사용 시 명시적인 동기화가 필요할 수 있습니다.
- 성능 테스트: 실제 사용 환경에서 성능 테스트를 수행하여 최적의 방식을 선택하세요.
결론
HashMap을 멀티스레드 환경에서 안전하게 사용하기 위해서는 상황에 맞는 적절한 동기화 방식을 선택해야 합니다. ConcurrentHashMap은 대부분의 경우에 좋은 선택이 될 수 있지만, 특정 요구사항에 따라 다른 방식이 더 적합할 수 있습니다.
'자료구조' 카테고리의 다른 글
HashMap과 HashTable의 차이 (1) | 2024.09.02 |
---|---|
해시 충돌 해결 방법: Chaining vs Open Addressing (0) | 2024.09.01 |
[자료구조] Hash Collision 개념 (0) | 2021.06.21 |
[자료구조] Binary Search Tree (0) | 2021.06.06 |
[자료구조] Graph와 Tree의 차이점에 대해서 설명 (0) | 2021.06.02 |
Comments