Lewis's Tech Keep

[JAVA] concurrentHashMap 이란, 왜 null을 허용하지 않는 지 본문

Java/JAVA Native

[JAVA] concurrentHashMap 이란, 왜 null을 허용하지 않는 지

Lewis Seo 2021. 10. 6. 23:07

concurrentHashMap유래


 - 일반적 hashmap은 thread-safe 하지 않다. (=멀티 쓰레드 환경에서 자원의 안정성, 동시성을 보장할 수 없음)

 - thread-safe 한 hashmap의 구조를 위하여 JAVA 1.5 버전 이전에는 hashTable 이나 synchronized map 이 쓰였다.

 - concurrentHashMap은 JAVA 1.5 버전부터 소개되었다고 한다.

 

 

Hashtable, synchronized mapconcurrentHashMap차이


 - hashtable, synchronized map은 동기화 시 전체에 lock을 걸지만, concurrentHashMap은 일부에만 lock을 건다.

 - concurrency level에 기반해 map을 여러 파트로 나누고 업데이트 동작이 일어나는 동안 오직 그 부분에만 lock을 수행한다. 기본 concurrency level은 16이다.

 - concurrentHashMap에서는 동기화 작업 시에는 객체가 concurrency level에 기반세그먼트로 나뉜다.

 - 여기서 세그먼트는 concurrentHashMap 내부 data structure이다. 그리고 32개로 설정되어 있기 떄문에 한번에 최대 32개의 스레드가 관리될 수 있다는 것을 의미한다고 한다. (최대 갯수는 65536개 이지만 segmens core 자체가 32개 이기때문에 효율은 낮다고 적혀있다. 테스트 필요)

 - 즉 concurrency level이란 map에서 동시에 업데이트되는 쓰레드의 갯수

 - 따라서 기본 값일 때는 16개의 쓰레드가 동시다발적으로 map에 동작을 수행할 수 있게 되는 것을 의미한다.

if (map.get(key) == null){
    return map.put(key, value);
} else{
    return map.get(key);
}

 - 위의 소스는 concurrentHashMap에서는 원하는 대로 동작하지 않는다. 왜냐하면 map 전체에 lock이 걸리지 않기 때문이다.

 - 즉 A쓰레드가 put을 하는 도중에 B쓰레드가 get을 요청한다면 B쓰레드는 null을 받게 된다. concurrentHashMap은 요청 상태에서 가장 최근에 완료된 갱신 작업 결과를 보여주기 때문이다.

 - 하지만 hashtable이라면 전체에 lock이 걸리기 때문B쓰레드는 A쓰레드의 결과 값을 받게 될 것이다.

 - 그래서 concurrentHashMap에서는 putIfAbsent(key, value)를 제공하고 있다.

 

 

 

concurrentHashMapnull을 허용하지 않는 이유


 - 개인적으로 너무나 궁금했다. 일단 concurrentHashMapnull을 허용하지 않는다. hashtable허용하지 않지synchronized mapnull을 허용한다.

The main reason that nulls aren't allowed in ConcurrentMaps 
(ConcurrentHashMaps, ConcurrentSkipListMaps) is that ambiguities 
that may be just barely tolerable in non-concurrent maps can't be accommodated. 
The main one is that if map.get(key) returns null, 
you can't detect whether the key explicitly maps to null vs the key isn't mapped. 
In a non-concurrent map, you can check this via map.contains(key), but in a concurrent one, 
the map might have changed between calls.

 (* 해석 중에 barely tolerable 이라는 것에 대한 의미를 아직 잘 모르겠어서 100% 믿지는 말고 어느정도만 믿어주시면 감사하겠습니다.)

(* barely tolerable, 나는 이것을 거의 다루지 않거나 신경쓰지 않아도 되는 처럼 생각 중이다.)

 - 위와 같이 적혀있는데 내가 이해하기엔 null을 허용하지 않는 가장 주된 이유로는

   non-concurrent map들(ex. hashmap)에서는 거의 참지 않아도 되는(barely tolerable) 모호성을 수용할 수 없기 때문이다.

 - concurrentHashMap이 null을 return한다고 가정하면, 이것이 map에 명시적으로 null이라고 한 것 인지, 아니면 원래 아예 없어서 null 인지 알 수 없다. (= detect 할 수 없다.)

 - non-concurrent map들의 구조라면 contains(key)를 이용해서 확인하면 되지만, concurrent 에서는 이게 멀티 쓰레드 간이나 어떤 호출 사이바뀔 수 있다.

 - 따라서 concurrentHashMap 구조에서는 null을 허용하지 않는다고 한다.

 

 

 

그래도 null을 허용하는 thread-safe한 map 구조만들고 싶을 때


 - Collections.synchronizedMap에 hashMap을 선언해서 쓰는 방법이 존재한다.

 - ex. Map map = Collections.synchronizedMap(new HashMap());

 


- 참고 링크 :

https://doorisopen.github.io/developers-library/Java/2020-07-08-java-hashmap-and-thread-safe

 

취준생에서 가치 있는 개발자가 되기까지 💪

 

doorisopen.github.io

https://highlyscalable.blogspot.com/2014/06/java-concurrenthashmap.html

 

Java ConcurrentHashMap

프로그래밍에 대한 시시콜콜한 팁, 잡다한 지식, 신기술 리뷰를 공유하는 기술 블로그

highlyscalable.blogspot.com

https://www.geeksforgeeks.org/concurrenthashmap-in-java/

 

ConcurrentHashMap in Java - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

https://dzone.com/articles/how-concurrenthashmap-works-internally-in-java

 

How ConcurrentHashMap Works Internally in Java - DZone Java

 

dzone.com

https://stackoverflow.com/questions/698638/why-does-concurrenthashmap-prevent-null-keys-and-values/9298113

 

Why does ConcurrentHashMap prevent null keys and values?

The JavaDoc of ConcurrentHashMap says this: Like Hashtable but unlike HashMap, this class does not allow null to be used as a key or value. My question: Why? 2nd question: Why doesn't Hashtable

stackoverflow.com

http://cs.oswego.edu/pipermail/concurrency-interest/2006-May/002485.html

 

[concurrency-interest] Handling Null Values in ConcurrentHashMap

 

cs.oswego.edu

https://stackoverflow.com/questions/5699794/thread-safe-map-with-null-key-capability

 

Thread-safe map with null-key capability

I need a multi-threaded Map object to use in my web server's caching, and I need to have null keys. HashMap allows me to have null keys, but ConcurrentHashMap doesn't. I tried to create a synchron...

stackoverflow.com

 

Comments