Thread-safe 하고, 성능도 고려된 HashMap
1) 키-값 삽입, 조회, 삭제
2) 조건부 연산 (putIfAbsent, computeIfAbsent, merge)
3) 병렬 루프 처리 (forEach, reduce)
* Thread-safe
: 멀티스레드 환경에서 코드나 객체가 동시에 접근돼도 문제가 발생하지 않도록 설계된 상태
? 왜 ConcurrentHashMap 은 Thread-safe 할까 ?
내부 구조 및 동시성 제어 기법
1. CAS (Compare-And-Swap) + Synchronized 최소화 (Java 8 이후)
Java 8부터는 Segment 대신 버킷 단위 락 + CAS 연산을 도입해 더 세밀한 락 제어가 가능해졌습니다.
- CAS 연산: 특정 조건이 만족될 때만 값을 변경하는 락 없는 동시성 기법입니다.
- synchronized: 필요 시 최소한의 범위에서만 사용합니다 (성능 저하 방지).
2. 읽기 연산은 락 없이 처리 (약한 일관성 제공)
대부분의 읽기 연산은 락 없이도 동작하며, 이는 락 경쟁을 줄여 성능을 높입니다.
데이터는 약간 과거 상태일 수 있지만, 일관된 상태로 읽혀집니다.
3. 트리화(Treeification)
충돌이 많은 버킷은 LinkedList → Red-Black Tree로 변환되어 검색 속도를 유지합니다.
4. 원자적 메서드 제공
동시성 환경에서도 안전하게 사용할 수 있도록 다양한 원자적 메서드를 제공합니다
- putIfAbsent() : 값이 없을 경우에만 삽입
- computeIfAbsent() : 없을 경우 계산 후 삽입
- merge() : 기존 값과 새 값을 병합
! 주요 특징 !
| 항목 | 설명 |
| 구조 | 해시 테이블 기반, 버킷 단위 락 |
| 락 방식 | CAS + synchronized (필요 최소한만) |
| 읽기 성능 | 대부분 락 없이 처리 |
| 쓰기 성능 | 충돌을 줄이고 빠르게 처리 |
| thread-safe | 완전 지원 (단, null 키 or 값은 불가) |
| 사용 환경 | 병렬 캐시, 통계 집계, 요청 처리 등 |
예시 환경 및 코드
- 다수의 스레드가 동시에 맵을 읽고/쓰는 환경
- 공유 캐시, 통계 수집, 중복 작업 방지 등 병렬 처리가 필요한 상황
- HashMap은 위험하고, Hashtable은 느릴 때
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
// 안전한 삽입
map.putIfAbsent("coke", 1);
// 원자적 병합
map.merge("coke", 1, Integer::sum);
// 락 없이 병렬 읽기 가능
map.forEach((key, val) -> System.out.println(key + ": " + val));
'CS 정리' 카테고리의 다른 글
| DB 샤딩 vs 파티셔닝, 데이터 분산 처리 (0) | 2025.06.23 |
|---|---|
| 락(Lock), 동시성 제어 (0) | 2025.06.17 |
| Java 키워드 모음: static, final, synchronized, abstract, transient (0) | 2025.05.28 |
| Java 대용량 데이터 처리 (6) - 멀티 쓰래드/병렬 처리 (0) | 2025.05.04 |
| Java 대용량 데이터 처리 (5) - 캐시 계층 활용(L1, L2, DB) (2) | 2025.05.02 |