ConcurrentHashMap (JDK 1.5+) và Collections.synchronizedMap() đều cung cấp thread-safety cho Map, nhưng cơ chế khóa và hiệu suất khác biệt lớn.
Bảng so sánh chi tiết
| STT | Tiêu chí | ConcurrentHashMap | Synchronized HashMap |
|---|---|---|---|
| 1 | Loại triển khai | Class triển khai ConcurrentMap, Serializable |
Phương thức tĩnh Collections.synchronizedMap() trả về wrapper |
| 2 | Cơ chế khóa | Khóa ở mức bucket/segment (striping) - Java 8+: CAS + synchronized trên node đầu bucket | Khóa toàn bộ Map (single lock) |
| 3 | Hiệu suất | Cao - cho phép concurrent read/write nhiều thread | Thấp - chỉ 1 thread truy cập tại một thời điểm |
| 4 | Null key/value | Không cho phép null key hoặc null value | Cho phép null key và null value |
| 5 | ConcurrentModificationException | Không ném (iterator weakly consistent) | Iterator ném exception nếu map bị sửa đổi khi đang iterate |
Ví dụ SynchronizedMap
Map<Integer, String> map = new HashMap<>();
map.put(1, "IBM");
map.put(2, "Dell");
Map<Integer, String> syncMap = Collections.synchronizedMap(map);
// Cần synchronized khi iterate:
synchronized(syncMap) {
for (String v : syncMap.values()) { ... }
}
Ví dụ ConcurrentHashMap
Map<Integer, String> map = new ConcurrentHashMap<>();
map.put(1, "IBM");
map.put(2, "Dell");
// Không cần synchronized khi iterate
for (String v : map.values()) { ... } // An toàn, weakly consistent
Đặc điểm nâng cao ConcurrentHashMap (Java 8+)
- Sử dụng CAS (Compare-And-Swap) + synchronized trên node đầu bucket thay vì segment locking.
- Phương thức atomic:
putIfAbsent,computeIfAbsent,merge,forEach,replaceAll. - Iterator weakly consistent: phản ánh trạng thái map tại thời điểm tạo iterator, không ném
ConcurrentModificationException.
Khi nào dùng cái nào?
- ConcurrentHashMap: Môi trường high-concurrency, hiệu suất quan trọng, Java 5+.
- SynchronizedMap: Đơn giản, low-concurrency, cần null key/value, hoặc legacy code.