실무 JUnit Test에서 ConcurrentHashMap을 사용해야 하는 이유
Java

실무 JUnit Test에서 ConcurrentHashMap을 사용해야 하는 이유

반응형

ConcurrentHash Map vs HashMap

  • 개발을 하다 보면 DB에 값을 저장하기 전에 메모리 영역에서 값을 저장하고 테스트해야 할 때 가 있다
  • 이때 아래와 같이 간단 한 맴버를 저장하는 MemoryRepository가 있다고 가정해보자
  • 안에는 맴버의 아이디 값과 멤버를 저장하는 HashMap 구조를 사용했다.
import java.util.HashMap;
import java.util.Map;

public class MemoryMemberRepository implements MemberRepository{
    private static Map<Long, Member> store = new HashMap<>();
    @Override
    public void save(Member member) {
        store.put(member.getId(), member);
    }

    @Override
    public Member findById(Long MemberId) {
        Member member = store.get(MemberId);
        return member;
    }
}
  • 이런 방식의 HashMap 사용 구조는 실무에서 위험하다.
  • 동시성 문제가 발생할 수 있는 부분에서 문제가 발생할 수 있기 때문이다.
  • 이런 문제를 해결하기 위해 사용하는게 ConcurrentHashMap이다.
  • 표를 통해 Map 선택지를 확인하고 왜 ConcurrrenetHashMap이 적합한지 확인해보자
  HashMap HashTable ConcurrentHashMap
Synchronized 가능 여부 X O O
Lock 개수 X 1 16
Multi_Thread 사용 적합 여부 X O O

HashMap

  • HashMap은 Synchronized를 위한 설정이 없다.
  • 그렇다 보니 Map 인터페이스중에서는 가장 빠르고 성능이 좋다.
  • 그러므로 Multi_Thred 환경이 아닌 경우에만 사용을 권장한다. (알고리즘 문제 풀 때?)

HashTable

  • HashMap과는 다르게 Synchronized가 존재한다.
  • 그렇기 때문에 Multi_Thread 환경에서 적합하다.
  • 하지만 동시에 작업을 하기에는 객체마다 가지고 있는 Lock 개수가 1개이기 때문에 병목 현상으로 인한 성능 저하 현상이 발생하게 된다.
  • 운영체제 개념에서 배운 임계 구역에 진입하기 위해 Lock을 얻고 기다려야 하는 개념이다.

ConcurrentHashMap

  • HashTable의 발전 버전이 ConcurrentHashMap이라고 할 수 있다.
  • JDK 1.5 버전에서 출시하였으며 Synchronized가 존재한다.
  • 읽기 작업에서는 Synchronized가 존재하지 않고 쓰기 부분에만 Synchronized 설정이 되어있다.
  • 쓰기 부분에 lock이 16개로 구성되어있으며 기존의 HashTable의 성능 저하 현상이 개선되어있습니다.

정리

  • Single_Thred 환경에서는 HashMap을 사용하고
  • Multi_Thread 환경에서 개발을 진행할 때는 ConcurrentHashMap을 사용하자

 

반응형