[JAVA] HashMap,HashTable,ConcurrentHashMap 비교

Jongmyung Choi·2022년 10월 23일
2
post-thumbnail
post-custom-banner

HashMap은 Java에서 Map 인터페이스를 구현하고 있는 클래스 중 하나이다.

key:value 가 1:1 로 Mapping 되고 삽입, 삭제, 검색의 시간복잡도가 평균적으로 O(1) 을 보여주는 좋은 이점을 가지고 있다.

이런 좋은 성능 때문에 자주 사용하는데 동시성 문제가 고려되지 않기 때문에
→ Threadsafe 하지 못함 → Multi-Thread에서 동기화처리 필요 !
실무에서는 ConcurrentHashMap, AtomicLong 을 사용한다고 한다.

면접에서도 자주 등장하는 HashMap 의 자료구조 및 동작원리 와 ConcurrentHashMap 에 대해서도 정리해보자.

HashMap

HashMap의 내부 구조는 배열(array) 로 되어 있으며 해싱(hashing)을 통하여 데이터가 저장될 인덱스를 구한다.

  1. key 값을 해싱함수에 넣은 후 인덱스를 산출한다.
  2. 인덱스에 데이터를 저장한다.

HashMap vs Hashtable

Key, Value 형식의 데이터를 저장하는 자료구조로 큰 맥락에서는 동일하지만
세가지 차이점을 보인다.

  • NULL 허용 여부
  • 동기화 여부
  • Enumuration 여부

HashMap

public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable {

    public V get(Object key) {}
    public V put(K key, V value) {}
}

Java 의 HashMap 클래스를 보면 synchronized 키워드가 존재하지 않는다. 따라서 성능은 좋지만 Multi-Thread 환경에서 사용할 수 없다.
→ 신뢰성과 안정성이 떨어진다.

NULL을 허용하지 않는다.

Enurmation을 제공하지 않는다.
→Fail-fast Iterator

Hashtable

public synchronized V get(Object key){
	Entry<?,?> tab[] = table;
    int hash = key.hashCode();
    .
    .
    .
}
public synchronized V put(K key, V value) {
	.
    .
    .
}

get(),put() 메서드를 확인해보면 synchronized 하게 구현 되어 있음을 확인 할 수 있다.

→ 동기화 처리가 되어 있다. → 데이터의 무결성 보장


NULL을 허용한다.

not fail-fast Enumeration 을 제공한다.

📢 Enurmation vs Iterator

Enumeration과 Iterator 의 가장 큰 차이점은 fail-fast 방식 개념이다.

콜렉션 클래스들은 저장된 객체들에 대한 순차적 접근을 제공한다.

Enumeration은 순차적 접근 시 콜렉션 객체에 변경이 일어나도 이를 무시하고, 끝까지 동작한다.

Iterator는 순차적 접근이 모두 끝나기 전에 콜렉션 객체에 변경이 일어날 경우 순차적 접근이 실패되면서 예외를 return하게 되는데 이를 fail-fast 방식이라고 부른다.

HashMap vs HashTable 정리

ConcurrentHashMap

  • HashMap의 Multi-Thread 환경에서의 동기화 문제를 보완했다
  • HashTable 보다 좋은 성능을 가진다.
  • key,value 에 NULL값을 허용하지 않는다.
  • Fail-Safe Iterator를 지원한다.

🙋‍♂️ HashTable 보다 왜 좋은 성능을 가지는가?

HashTable은 동기화시 synchronized 키워드를 이용하여 메소드 전체에 락을 거는데에 반해 ConcurrentHashMap은 lock striping 을 이용하여 내부적으로 16개의 세그먼트를 두고 세그먼트마다 별도의 락을 건다.

Atmoic Long

  • AtomicLong은 Long 자료형을 갖고 있는 Wrapping 클래스이다.
  • Thread-safe로 구현되어 멀티쓰레드에서 synchronized 없이 사용할 수 있다.
  • 또한 synchronized 보다 적은 비용으로 동시성을 보장할 수 있다.

결론

Single-Thread 환경에서는 HashMap을 사용하고
Multi-Thread 환경에서는 HashTable ConcurrentHashMap 을 사용하자.

참고

https://tomining.tistory.com/169

https://devlog-wjdrbs96.tistory.com/269

https://www.dineshonjava.com/difference-between-hashmap-and/

profile
총명한 개발자
post-custom-banner

0개의 댓글