HashMap vs ConcurrentHashMap

SeungJoo
|2025. 4. 10. 23:37
728x90
반응형

HashMap vs ConcurrentHashMap - 실시간 채팅 프로젝트에서 왜 ConcurrentHashMap을 사용하나?

HashMap 이란?

HashMap은 Java의 Map 인터페이스를 구현한 대표적인 자료 구조로, Key의 hashCode() 값을 이용해 데이터를 빠르게 저장하고 검색할 수 있습니다.

장점

  • 빠른 성능 : 평균적으로 O(1)의 시간복잡도로 검색, 삽입, 삭제가 가능합니다.
  • 단일 스레드 환경에서 최적 : 멀티스레드 처리를 고려하지 않을 경우, 가장 빠르고 효율적인 Map입니다.

단점

  • 스레드에 안전하지 않음
    • 여러 스레드가 동시에 접근할 경우, 예외 발생 및 데이터 정합성 문제가 발생할 수 있습니다.
  • 발생 가능한 문제
    • ConcurrentModificationException : 반복 도중 다른 스레드가 구조를 바꾸면 예외 발생합니다.
    • 데이터 손실 : 동시 쓰기 시 값 덮어쓰이거나 누락될 수 있습니다.
Map<String, String> userMap = new HashMap<>();
userMap.put("id1", "Alice");
userMap.put("id2", "Bob");
String name = userMap.get("id1");

ConcurrentHashMap 이란?

ConcurrentHashMap은 Java에서 제공하는 멀티스레드 환경에 안전하게 동작하는 Map 구현체입니다.

Map<String, String> map = new ConcurrentHashMap<>();
map.put("user1", "session1");

 

장점

  • Thread-safe : 여러 스레드가 동시에 접근해도 데이터 충동 없이 안전하게 동작합니다.
  • 높은 성능 유지 : 전체를 동기화하지 않고, 버킷 단위로 락을 걸어 경합 최소화 합니다.
  • 원자적 연산 지원 : pubIfAbsent, computerIfAbsent, merge 같은 메서드를 통해 동시성 문제없는 연산이 가능합니다.

내부 동작 방식

연산 동작방식
get() 락 없이 동작
put(), remove() 해당 버킷 부분 락
computer() CAS 기반 낙관적 락 방식 일부 사용

1. 실시간 채팅에서 ConcurrentHashMap이 필요한 이유

private final Set<String> sessions = ConcurrentHashMap.newKeySet();
  • 동시에 여러 사용자가 접속/이탈 해도 안전하게 세션 관리 가능합니다.
  • 내부적으로는 ConcurrentHashMap<String, Boolean> 기반의 KeySetView
  • 스레드 간 충돌 없이 sessionId 저장 및 삭제 가능합니다.

2. 일반 HashSet/HashMap을 사용할 경우 문제점

실시간 채팅에서는 여러 사용자가 동시에 다음과 같은 상황 발생합니다.

  • 동시에 여러 사용자가 접속 할 때 - connectHandle
  • 동시에 여러 사용자가 연결 종료 할 때 - disconnectHandle

이때 일반 HashSet, HashMap을 사용했다면?

private final Set<String> sessions = new HashSet<>(); // 위험
  • 이 구조는 동시 접근시 ConcurrentModificationException 발생 가능성 있습니다.
  • 또는 세션 ID가 정상적으로 추가/삭제되지 않아 메모리 누수가 발생합니다.
  • 심지어 동일한 세션 ID가 중복 저장되어 서버 리소스 낭비 가능합니다.

3.  ConcurrentHashMap.newKeySet()의 장점

ConcurrentHashMap<String, Boolean> backingMap = new ConcurrentHashMap<>();
Set<String> threadSafeSet = backingMap.keySet();
  • 다중 스레드 환경에서 안전하게 add/remove 가능합니다.
  • 현재 접속 중인 사용자 수를 정확히 파악할 수 있습니다.
  • 부분 락 및 lock-free 접근 덕분에 성능 저하 없습니다.
  • 세션 누수 없이 안정적인 메모리 관리 가능합니다.
728x90
반응형

'JAVA' 카테고리의 다른 글

IS-a와 HAS-a 관계  (0) 2025.04.25
인터페이스와 추상클래스  (0) 2025.04.10
팩토리 메서드 패턴  (0) 2025.02.17