(자바) HashTable, HashMap, ConcurrentHashMap

일단 ConcurrentHashMap 과 HashMap 의 차이점은 다 알고 있다는 전제하에 포스팅을 작성 한다.
이 포스팅을 하게된 이유는 사실 어떤분이 나에게 ConcurrentHashMap 과 HashMap 의 차이점을 아냐고 물어봤고
물론 알고 있어서 쏼라쏼라 대답을 했지만 (Multi-Threaded 환경에서 thread safe 여부) 거기에서 끝나지 않고
또 물어보시더라 ConcurrentHashMap 이 왜 Thread 에 safe 한지? 어떤 원리인지 아세요?
그래서 나는 사실 정확하게 알진 못했지만 대략 MySQL 의 innodb 처럼 row-level lock 걸듯이 접근하고 있는 해당 Key 값에
lock을 걸지 않을까요? 라고 대답을 했다.
이 대답은 후에 찾아 보니 반은 맞고 반은 틀리더라…
그리고 다시한번 정확하게 정리한다..
——————————————————————————————————
보통은 우리가 Multi-threaded 환경에서 key-value 저장소가 필요할때 자바에서 사용하는 것이
크게
1. HashTable
2. HashMap
3. ConcurrentHashMap
이렇게 있는데 파악을 하기 위해서 각 자바 source 를 까보았다.
가장 중요한 Get, Set 부분만 보면
1. HashTable

public synchronized V More ...get(Object key)
public synchronized V More ...put(K key, V value)
보이는가? 메소드 레벨에서 synchronized 를 걸어 버린다.
2. HashMap
얘는 볼것도 없이 synchronized 가 없다. 따라서 속도는 빠르지만 Multi-threaded 환경에서 그냥 쓰면 여러 Thread 에서 동시 접근시 Exception 이 난다.
3. ConcurrentHashMap
얘는 특이하게 synchronized 가 아니라 lock 을 사용한다.

V More ...put(K key, int hash, V value, boolean onlyIfAbsent) {
lock();
try {
int c = count;
if (c++ > threshold) // ensure capacity
rehash();
HashEntry[] tab = table;
.
.
.
처음에 이 부분만 보고 아싸 내 말이 맞았구나 했다. 하지만 찾아 보니
비슷은한데 CurrentHashMap 은 Map 자체를 Currency 레벨로 영역을 쪼개서 (기본이 16개)
해당 영역별로 lock을 거는 것이었다. 이 Lock 이름은 ReentrantLock 이라고 한다.
소스에서
CurrentHashMap 생성자중에

public More ...ConcurrentHashMap(int initialCapacity, float loadFactor, int concurrencyLevel) {
...
}

참고: http://blog.leekyoungil.com/?p=159

댓글

이 블로그의 인기 게시물

(네트워크)폴링방식 vs 롱 폴링방식

(ElasticSearch) 결과에서 순서 정렬

(18장) WebSocekt과 STOMP를 사용하여 메시징하기