ใน Java Collections Framework ถือเป็นโครงสร้างข้อมูลที่สำคัญที่สุดสำหรับการจัดเก็บและจัดการข้อมูล โดยมีการ implement หลายรูปแบบ เช่น Map, Set, List ซึ่งไม่เพียงช่วยให้จัดเก็บข้อมูลได้อย่างมีประสิทธิภาพเท่านั้น ยังรองรับการทำงานในสภาพแวดล้อม multi-threading อีกด้วย
HashMap
HashMap เป็นหนึ่งใน implementation ที่สำคัญของ Map interface ซึ่งจัดเก็บข้อมูลในรูปแบบ key-value pair แต่ HashMap ไม่ได้เป็น thread-safe หมายความว่า หากมีหลาย thread เข้าถึงและแก้ไข HashMap พร้อมกันอาจทำให้ข้อมูลเสียหายหรือเกิด infinite loop ได้
ConcurrentHashMap
ConcurrentHashMap ถูกออกแบบมาเพื่อแก้ไขปัญหา thread-safety โดยยังคงประสิทธิภาพสูง ใน Java 8 ขึ้นไป ใช้เทคนิค CAS (Compare-And-Swap) และ synchronized บนระดับ bucket แทนการใช้ segment locking แบบเก่า ทำให้หลาย thread สามารถอ่านและเขียนพร้อมกันได้โดยไม่บล็อกทั้ง Map
ตารางเปรียบเทียบความแตกต่างหลัก
| ลำดับ | หัวข้อ | HashMap | ConcurrentHashMap |
|---|---|---|---|
| 1 | Thread Safety | ไม่เป็น thread-safe ไม่เหมาะสำหรับ multi-threaded environment | เป็น thread-safe เหมาะสำหรับ multi-threaded environment |
| 2 | กลไกการ Lock (Java 8+) | ไม่มีการ lock ใดๆ | ใช้ CAS + synchronized บนระดับ bucket/node ไม่ lock ทั้ง Map |
| 3 | Null Key/Value | อนุญาตให้มี null key (1 ตัว) และ null values ได้ | ห้ามมี null key และ null values จะโยน NullPointerException |
| 4 | Iterator Behavior | Fail-fast: โยน ConcurrentModificationException หากโครงสร้างเปลี่ยนแปลงระหว่าง iteration | Weakly consistent: ไม่โยน exception แสดงสถานะของข้อมูลในขณะนั้น |
| 5 | ประสิทธิภาพ (Single-thread) | เร็วกว่า เพราะไม่มี overhead ของ synchronization | ช้ากว่าเล็กน้อยจาก overhead แต่ זניח |
| 6 | ประสิทธิภาพ (Multi-thread) | ต้อง wrap ด้วย Collections.synchronizedMap() จะ lock ทั้ง Map ทำให้ throughput ต่ำ | สูงกว่ามาก เพราะอนุญาตให้หลาย thread เข้าถึงต่าง bucket พร้อมกัน |
| 7 | เวอร์ชันที่นำเสนอ | JDK 1.2 | JDK 1.5 (ปรับปรุงใหญ่ใน Java 8) |
เมื่อไหร่ควรใช้哪一个?
- HashMap - ใช้ใน single-threaded environment หรือเมื่อมีการ synchronize ภายนอกเอง
- ConcurrentHashMap - ใช้ใน multi-threaded environment ที่ต้องการประสิทธิภาพสูงและ thread-safety
หมายเหตุ: ใน Java 8+ ConcurrentHashMap ยังเพิ่มเมธอดที่สะดวก เช่น computeIfAbsent, merge, forEach ซึ่งเป็น atomic operations ทำให้เขียน concurrent code ได้ง่ายขึ้น