Từ Java 8, ConcurrentHashMap bỏ hẳn cơ chế segment cũ. Thay vào đó:
- Bin (bucket) rỗng → chèn bằng CAS, hoàn toàn không lock.
- Bin đã có phần tử → synchronized trên node đầu của riêng bin đó, không phải toàn bảng.
- Đọc (get) không lock: node dùng field volatile, nên thấy giá trị mới nhất đã ghi xong.
Mức tranh chấp vì thế tỉ lệ với số bin bị đụng, không phải số thread.
Cạm bẫy chính: từng thao tác riêng lẻ là atomic, nhưng ghép nhiều thao tác thì không.
// SAI: check rồi act - hai thread cùng lọt qua containsKey
if (!map.containsKey(k)) map.put(k, expensive(k));
// ĐÚNG: một thao tác atomic
map.computeIfAbsent(k, expensive);
map.merge(k, 1, Integer::sum); // đếm an toàn
map.putIfAbsent(k, v);Hai điểm hay hỏi thêm:
- Bên trong computeIfAbsent/compute, không được đụng lại chính map đó — đang giữ lock trên bin, thao tác lồng nhau có thể gây deadlock hoặc treo. Javadoc ghi rõ hàm ánh xạ phải ngắn và không cập nhật map.
- size() và iterator phản ánh trạng thái tại một thời điểm nào đó trong quá trình duyệt, không phải một snapshot nhất quán — không dùng làm căn cứ cho quyết định cần chính xác tuyệt đối.
- key/value không được null, khác HashMap: với map đồng thời, get() trả null sẽ không phân biệt được "không có key" và "giá trị là null".