Development/Java

[기술면접준비] 멀티스레드 상황에서 어떤 Map 구현체를 사용해야할까?

bbubbush 2023. 4. 5. 15:57

들어가며

기술면접에서 면접관이 SynchronizedMap과 ConcurrentHashMap의 차이를 물어봤다. 근데 ConcurrentHashMap를 몰라서 대답을 못했다. 면접을 복기할 겸, Map에 대해 부족한 부분을 공부할 겸 포스팅을 쓴다.

 

 

Q. HashMap과 HashTable의 차이는 무엇인가요? 

A. 가장 큰 차이는 HashTable은 동기화를 지원하는 반면, HashMap은 동기화를 지원하지 않습니다.
다만 HashTable은 모든 메서드에 동기화를 지원하는 만큼 상대적으로 느립니다. 또한 Iterator를 사용하는 중에 데이터 변경이 일어나면 Exception이 발생하게 됩니다. 또 key나 value에 null을 허용하지 않는 특징도 있습니다.
HashMap은 반대로 동기화를 지원하지 않아 빠르고, Iterator 사용 중에 데이터 변경도 가능하며, key, value에 null도 허용이 됩니다.

컬렉션 프레임워크에 대한 질문을 하면 단골로 나오는 질문이 LinkedList, ArrayList 비교와 HashMap, HashTable 비교다. 성능에 초점을 두는 List의 질문과 달리 이 질문은 멀티스레드 환경에 대한 질문으로 이어질 가능성이 높다. 각 상황에 사용해야 하는 구현체와 그 이유를 정리해 두면 좋다.

 

여담으로 재밌는 것은 최근에 공부를 시작한 개발자들은 HashTable을 사용하거나 배운적이 없는 경우가 많다. 나 역시도 자바를 알게 된 지 7년 정도 되었지만, 처음 Map을 배울 때부터 HashMap을 썼다.

그래서 이 질문은 말 그대로 면접을 위한 공부가 아닐까 싶다. LinkedList와 ArrayList는 데이터를 조회하거나 변경하는 부분에서 성능의 차이가 생겨 실무에도 병행되지만, Map은 그냥 HashMap을 쓰고 멀티스레드 상황에만 ConcurrentHashMap를 쓴다.

 

실용적인 관점에서 질문을 다시 한다면 "Thread-safety한 Map을 선택한다면 어떤 것을 선택할까요?" 혹은 "싱글스레드, 멀티스레드 상황에서 각각 적합한 Map은 어떤 것일까요?" 등이 되지 않을까 싶다. 그래서 아래 질문이 꼭 같이 나온다.

 

 

Q. 그럼 동기화된 Map을 사용해야할 때는 HashTable을 사용하시나요?

A. ConcurrentHashMap을 사용할 것입니다. Thread-safety 한 Map은 HashTable, SynchronizedMap 등도 있지만 이들은 메서드 단위의 동기화 처리로 인해 성능이 느립니다. 반면 ConcurrentHashMap은 조회에 대해서는 비동기를 지원하면서, 데이터 변경에 대해서 부분적인 코드레벨의 동기화 처리로 성능과 Thread-safety를 모두 만족할 수 있는 최선의 선택이라고 판단되기 때문입니다.

지금까지 Thread-safety한 상황에서 개발한 적이 없어 ConcurrentHashMap을 몰랐다. 대신 이론적으로는 공부해 둔 내용이 있어 HashTable 대신 Collections.synchronizedMap을 사용한다고 알고 있었다. 이번 기회를 통해 자료를 찾아보니 '멀티스레드 환경의 Map = ConcurrentHashMap'이 그냥 공식처럼 사용해야겠다고 생각했다.

동일한 기능을 제공하는데 성능이 우수하다. 안 쓸 이유가 없다는 뜻이다.

 

코드로 잠깐 보면 아래와 같은 차이가 있다.

 

SynchronizedMap의 구현부. synchronized키워드가 메서드마다 들어있다.

 

ConcurrentHashMapdml put()의 내부 코드 인 putVal()의 일부

 

스크린샷을 보니 성능에 차이가 생길 수밖에 없다. 지금까지는 몰라서 못쓰고, 상황이 안돼서 못썼지만 이제는 확실히 알겠다. 알게 되니깐 면접관이 어떤 대답을 원하고 어떤 의도로 질문했는지도 이해가 간다.

 

마치며

이번에도 지난 면접의 쓰라림을 달래기 위해 포스팅을 해봤다. 다음 회사 면접에 꼭 이 내용이 나왔으면 좋겠다. 오늘도 하루만큼 성장함을 느낀다. 여러분에게도 도움이 되는 글이 되었길 바란다.