본문 바로가기
language/java

Java ConcurrentHashMap 기초 완벽 이해하기

by 죄니안죄니 2026. 5. 27.
반응형

Java ConcurrentHashMap 기초 완벽 이해하기

Java 멀티스레드 환경에서 가장 중요한 컬렉션 중 하나가 바로:

ConcurrentHashMap

입니다.

실무에서는:

  • 캐시(Cache)
  • 세션 저장
  • 동시 요청 처리
  • 실시간 데이터 집계
  • 멀티스레드 서버

등에서 매우 많이 사용됩니다.

초보 시절에는 보통:

HashMap의 Thread-safe 버전?
 

정도로 이해하기 쉽습니다.

하지만 실제로는:

  • synchronized 문제
  • CAS(Compare And Swap)
  • Lock 분할
  • CPU 동시성
  • non-blocking 알고리즘

까지 연결되는 매우 중요한 동시성 자료구조입니다.

이번 글에서는:

  • HashMap의 문제
  • synchronizedMap 한계
  • ConcurrentHashMap 구조
  • CAS 동작 원리
  • JDK7 vs JDK8 구조 차이
  • 실무 사용 전략

까지 깊게 정리해보겠습니다.


1. 왜 ConcurrentHashMap이 필요할까?

기본 HashMap 은:

Thread-safe 아님
 

입니다.


2. 무슨 문제가 생길까?

멀티스레드 환경에서:

 
map.put(...)
map.get(...)
 

동시 수행 시:

  • 데이터 유실
  • 무한 루프
  • 상태 꼬임

발생 가능.


3. 예시 상황

스레드 A:

 
map.put("A", 1);
 

스레드 B:

 
map.put("B", 2);
 

동시에 실행.


4. 왜 위험할까?

HashMap 내부는:

배열 + LinkedList(Tree)
 

구조.

동시 수정 시:

구조 일관성 깨질 수 있음
 

5. 과거 HashMap 실제 문제

JDK7 이전에는 resize 중:

무한 루프
CPU 100%
 

같은 문제 실제 존재.


6. 가장 단순한 해결 방법

대표:

 
Collections.synchronizedMap(...)
 

7. 예시

 
Map<String, String> map =
    Collections.synchronizedMap(
        new HashMap<>()
    );
 

8. 어떻게 동작할까?

내부적으로:

 
synchronized
 

사용.

즉:

한 번에 한 스레드만 접근
 

가능.


9. 문제점

매우 중요.

전체 Map Lock
 

걸림.


10. 결과

즉:

동시성 성능 매우 낮아짐
 

특히:

  • 읽기 많음
  • 요청 많음

환경에서 병목 발생.


11. 그래서 등장한 ConcurrentHashMap

ConcurrentHashMap 은:

동시성을 고려해 설계된 Thread-safe HashMap

입니다.


12. 핵심 목표

매우 중요.

Thread-safe
+
높은 동시성 성능
 

둘 다 달성 목표.


13. ConcurrentHashMap 특징


특징 설명
Thread-safe O
높은 동시성 O
읽기 성능 우수 O
전체 Lock 최소화 O

14. JDK7 구조

과거(JDK7)는:

Segment Lock
 

구조 사용.


15. Segment란?

HashMap을 여러 조각으로 분리.

예:

Segment 0
Segment 1
Segment 2
 

16. 왜 나눌까?

목표:

전체 Lock 방지
 

입니다.


17. 즉 동작 방식

스레드 A:

Segment 0 Lock
 

스레드 B:

Segment 2 Lock
 

이면 동시에 작업 가능.


18. 이것이 Lock Striping

즉:

Lock 분할 전략
 

입니다.


19. 그런데 JDK8에서 변경

매우 중요.

JDK8 이후는:

Segment 제거
 

되었습니다.


20. 왜 제거했을까?

더 높은 성능과 단순화 목적.


21. JDK8 핵심 구조

현대 ConcurrentHashMap은:

CAS + synchronized 최소 사용
 

구조.


22. CAS란?

Compare-and-swap 는:

값을 비교 후 원자적으로 교체하는 CPU 명령

입니다.


23. 핵심 아이디어

“값이 예상과 같으면 교체”
 

입니다.


24. 왜 중요할까?

락 없이:

원자적(atomic) 처리 가능
 

하기 때문.


25. 예시 개념

현재 값 = A
예상 값 = A
새 값 = B
 

이면 교체 성공.


26. 다르면?

다른 스레드가 이미 수정한 것.

즉:

재시도(retry)
 

수행.


27. ConcurrentHashMap 내부 전략

핵심:

읽기 대부분 lock 없음
 

입니다.


28. 왜 읽기 빠를까?

get()은 보통:

volatile + CAS 기반
 

으로 안전성 확보.


29. put() 시에는?

필요 최소 범위만:

 
synchronized
 

사용.


30. 즉 큰 차이

synchronizedMap:

전체 Lock
 

ConcurrentHashMap:

bucket 단위 최소 Lock
 

31. 그래서 동시성 향상

특히:

읽기 많을수록 매우 강력
 

합니다.


32. 내부 구조

현대 구조:

배열
+
Node
+
CAS
+
부분 synchronized
 

조합.


33. TreeNode도 사용

Hash 충돌 많아지면:

LinkedList → Tree
 

변환.

HashMap과 유사.


34. size()도 복잡하다

멀티스레드 환경에서는:

정확한 size 계산 어려움
 

가능.


35. 그래서 내부적으로

  • CounterCell
  • CAS
  • 분산 카운팅

등 사용.


36. null 금지

매우 중요.

ConcurrentHashMap은:

null key/value 허용 안 함
 

37. 왜 null 금지할까?

멀티스레드 환경에서:

null 의미 모호
 

해지기 때문.

예:

값 없음?
삭제됨?
아직 로딩 안 됨?
 

구분 어려움.


38. putIfAbsent()

실무에서 매우 중요.

 
map.putIfAbsent(key, value);
 

39. 의미

없을 때만 저장
 

원자적으로 수행.


40. 왜 중요할까?

멀티스레드에서:

check-then-act 문제
 

방지 가능.


41. computeIfAbsent()

실무에서 정말 많이 사용.

 
map.computeIfAbsent(
    key,
    k -> createValue()
);
 

42. 장점

중복 생성 방지
 

가능.

캐시 구현에 매우 중요.


43. ConcurrentHashMap vs synchronizedMap


항목 synchronizedMap ConcurrentHashMap
Thread-safe O O
전체 Lock O X
읽기 성능 낮음 높음
동시성 낮음 높음
null 허용 O X

44. 실무 사용 사례

대표:

  • 캐시 저장소
  • 사용자 세션
  • 실시간 카운팅
  • 메모리 기반 상태 관리

45. ConcurrentHashMap도 만능은 아니다

매우 중요.

복합 연산은 여전히 주의 필요.


46. 위험한 예

 
if (!map.containsKey(key)) {
    map.put(key, value);
}
 

멀티스레드에서 안전하지 않을 수 있음.


47. 왜 위험할까?

중간에 다른 스레드가 수정 가능.

즉:

Race Condition
 

발생 가능.


48. 그래서 putIfAbsent 사용

원자적 처리 필요.


49. 실무에서 자주 하는 실수

1) HashMap을 멀티스레드에서 사용

매우 위험.


2) synchronizedMap이면 충분하다고 생각

고부하에서 병목 가능.


3) ConcurrentHashMap인데 복합 연산 안전하다고 착각

주의 필요.


4) null 저장 시도

ConcurrentHashMap은 금지.


50. 핵심 흐름 요약

HashMap 문제
↓
전체 Lock 병목
↓
ConcurrentHashMap 등장
↓
CAS + 최소 Lock 사용
↓
높은 동시성 성능 제공
 

51. 가장 중요한 핵심 한 줄

ConcurrentHashMap은
“락을 최소화하면서 Thread-safe를 제공하는 고성능 동시성 Map”
 

입니다.


52. 정리

ConcurrentHashMap은 단순 Thread-safe Map이 아닙니다.

실제로는:

  • CAS
  • volatile
  • synchronized 최소화
  • lock striping
  • non-blocking 동시성

전체와 연결되는 Java 동시성 핵심 자료구조입니다.

특히 실무에서는:

  • putIfAbsent()
  • computeIfAbsent()
  • synchronizedMap 차이
  • null 금지 이유
  • Race Condition

을 정확히 이해하는 것이 매우 중요합니다.

다음 글에서는:

람다 표현식(Lambda)

를 함수형 인터페이스, 익명 클래스 차이, JVM 내부 동작, Stream 연결까지 포함해서 깊게 정리해보겠습니다.

반응형

댓글