HashMap 사용 시 동시성 문제를 해결하기 위해 ConcurrentHashMap을 사용한다고 한다.
본 글은 HashMap과 ConcurrentHashMap에 대한 비교 내용이다.

1) Thread Safe
주요 차이점은 ConcurrentHashMap은 내부적으로 동기화되어 스레드로부터 안전하다는 것. HashMap은 Collections.synchronizedMap() 메서드를 사용하여 외부적으로 동기화할 수 있다.
2) Internal Structure
ConcurrentHashMap의 모든 작업이 동기화되는 것은 아니다. 추가 및 삭제와 같은 수정 작업만 동기화되고 읽기 작업은 동기화되지 않는다.
HashMap을 Collections.synchronizedMap() 메서드를 사용하여 외부에서 동기화하는 경우, 모든 작업이 동기화 된다. 이렇게 하면 속도가 느려지는 문제가 있다.
3) Introduction Into Java Collection Framework
HashMap은 JDK 1.2 부터 Java Collection Framework에 포함되었고, ConcurrentHashMap은 나중에 Java Collection Framework에 동시성 패키지의 일부로 도입 되었음. ConcurrentHashMap은 레거시 클래스인 HashTable의 대안으로 취급된다. (HashTable 클래스의 메서드에는 synchronized 키워드 사용하고 있어 스레드 세이프하지만, 속도 저하 이슈가 있음.)
4) Null Keys And Null Values
HashMap은 하나의 null 키와 여러 null 값을 허용한다.
ConcurrentHashMap은 null 키와 null 값을 허용하지 않는다.
5) Fail-Fast Vs Fail-Safe
HashMap의 Iterator는 fail-fast 방식을 사용. Iterator가 생성된 이후 Map이 수정되면 즉시 ConcurrentModificationException 예외가 발생하여 프로그램이 중단된다.
ConcurrentMap의 Iterator는 fail-safe 방식을 사용. Iterator가 생성된 이후 Map이 수정되어도 예외가 발생하지 않는다. Iterator가 반환하는 값은 Iterator가 생성된 시점에서의 Map 상태를 기반으로 하기 때문에 항상 일관된 값을 반환한다. 즉, 수정된 값을 반영하지 않는다.
6) Performance
ConcurrentHashMap의 수정 작업만 동기화 된다. 따라서 ConcurrentHashMap의 추가 또는 삭제 작업은 HashMap 보다 느리다.
읽기 작업은 HashMap과 ConcurrentHashMap 모두 동기화하지 않기 때문에 동일한 성능을 보인다.
7) When To Use What?
HashMap은 내부에서 동기화를 제공하지 않기 때문에 단일 스레드(single-threaded) 애플리케이션에 적합하다.
ConcurrentHashMap은 내부에서 동기화(synchronization)를 제공하여 여러 개의 스레드가 동시에 맵에 접근하고 수정할 수 있도록 하기 때문에 동시 다중 스레드(concurrent multi-threaded) 애플리케이션에 적합하다.
[출처 및 참고]
https://javaconceptoftheday.com/hashmap-vs-concurrenthashmap-in-java/