Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

ความแตกต่างระหว่าง HashMap และ ConcurrentHashMap

ใน 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 ได้ง่ายขึ้น