Cả 2 thread-safe, nhưng cách hoàn toàn khác.
| Hashtable (legacy) | ConcurrentHashMap (Java 5+) | |
|---|---|---|
| Lock | synchronized toàn method — 1 thread tại 1 thời điểm | Bucket-level + CAS (lock-free read) |
| Throughput multi-thread | Thấp (contention cao) | Cao hơn nhiều lần |
| Iterator | Fail-fast → CME | Weakly-consistent — không throw |
| Compound op atomic | ❌ | ✅ putIfAbsent, compute, merge |
Java 8+: ConcurrentHashMap bỏ segment, dùng CAS + synchronized per-node, bucket >8 entry biến thành red-black tree.
java
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
// Compound op ATOMIC
map.compute("counter", (k, v) -> v == null ? 1 : v + 1);
map.merge("hits", 1, Integer::sum);Tránh anti-pattern:
java
// ❌ SAI — race condition giữa get và put
if (!map.containsKey(key)) map.put(key, computeValue());
// ✅ ĐÚNG — atomic
map.computeIfAbsent(key, k -> computeValue());Default 2026: ConcurrentHashMap cho mọi shared map. Hashtable chỉ còn ý nghĩa lịch sử.