ConcurrentHashMap เทียบกับ HashMap ที่ซิงโครไนซ์


148

อะไรคือความแตกต่างระหว่างการใช้คลาส wrapper SynchronizedMap,, a HashMapและConcurrentHashMap?

เป็นเพียงความสามารถในการปรับเปลี่ยนในHashMapขณะที่ iterating มัน ( ConcurrentHashMap)?

คำตอบ:


120

ซิงโครไนซ์HashMap

  1. แต่ละวิธีจะซิงโครไนซ์โดยใช้การล็อกระดับวัตถุ ดังนั้นวิธีการรับและวางบน synchMap จึงได้รับการล็อค

  2. การล็อกคอลเลกชันทั้งหมดเป็นค่าใช้จ่ายด้านประสิทธิภาพ ในขณะที่เธรดหนึ่งล็อกไว้ที่ล็อคไม่มีเธรดอื่นใดสามารถใช้คอลเลกชันได้

ConcurrentHashMap เปิดตัวใน JDK 5

  1. ไม่มีการล็อคที่ระดับวัตถุการล็อคจะละเอียดยิ่งขึ้น สำหรับ a ConcurrentHashMapล็อคอาจอยู่ในระดับที่ฝากข้อมูล hashmap

  2. ผลของการล็อกระดับล่างคือคุณสามารถมีตัวอ่านและตัวเขียนพร้อมกันซึ่งเป็นไปไม่ได้สำหรับคอลเลกชันที่ซิงโครไนซ์ สิ่งนี้นำไปสู่การปรับขนาดได้มากขึ้น

  3. ConcurrentHashMapห้ามโยน a ConcurrentModificationExceptionหากเธรดหนึ่งพยายามแก้ไขขณะที่เธรดอื่นวนซ้ำ

บทความนี้Java 7: HashMap vs ConcurrentHashMap เป็นการอ่านที่ดีมาก แนะนำเป็นอย่างยิ่ง


7
ดังนั้นอะไรคือความแตกต่างระหว่างHashtableและSynchronized HashMap?
roottraveller

1
ระหว่าง ConcurrentHashMap และ HashMap ที่ซิงโครไนซ์แล้วคุณแนะนำแบบไหน?
Blunderchips

2
มันพูดถึงมูลค่าที่ConcurrentHashMap's size()ผลอาจจะออกจากวันที่ size()ได้รับอนุญาตให้ส่งคืนค่าประมาณแทนจำนวนที่แน่นอนตามหนังสือ "Java Concurrency in Practice" ดังนั้นวิธีนี้ควรใช้อย่างระมัดระวัง
Andrii Lisun

1
@roottraveller สำหรับ Hashtable และซิงโครไนซ์ HashMap stackoverflow.com/questions/8875680/…
Narendra Jaggi

89

คำตอบสั้น ๆ :

แผนที่ทั้งสองเป็นการใช้งานMapส่วนติดต่อแบบปลอดภัยของเธรด ConcurrentHashMapถูกนำมาใช้สำหรับปริมาณงานที่สูงขึ้นในกรณีที่คาดว่าจะเกิดพร้อมกันสูง

บทความของ Brian Goetz เกี่ยวกับแนวคิดที่อยู่เบื้องหลังConcurrentHashMapเป็นสิ่งที่อ่านได้ดีมาก แนะนำเป็นอย่างยิ่ง


1
ตอนนี้คืออะไร HashMap: โปรดทราบว่าการใช้งานนี้ไม่ได้รับการซิงโครไนซ์เพื่อป้องกันการเข้าถึงแผนที่โดยไม่ได้รับการซิงโครไนซ์โดยไม่ได้ตั้งใจ: Map m = Collections.synchronizedMap(new HashMap(...)); docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
X-HuMan

5
"บทความของ Brian Goetz ... อ่านดีมาก" - และยิ่งกว่านั้นก็คือหนังสือ "Java Concurrency in Practice" ของเขา
Alex Fedulov

31

ConcurrentHashMapเธรดปลอดภัยโดยไม่ซิงโครไนซ์แผนที่ทั้งหมด การอ่านสามารถเกิดขึ้นได้อย่างรวดเร็วในขณะที่เขียนเสร็จด้วยการล็อก


18

เราสามารถบรรลุความปลอดภัยของเธรดโดยใช้ทั้ง ConcurrentHashMap และ synchronisedHashmap แต่มีความแตกต่างมากถ้าคุณดูสถาปัตยกรรมของพวกเขา

  1. synchronisedHashmap

มันจะรักษาล็อคที่ระดับวัตถุ ดังนั้นหากคุณต้องการดำเนินการใด ๆ เช่นวาง / รับคุณต้องได้รับการล็อคก่อน ในเวลาเดียวกันเธรดอื่นไม่ได้รับอนุญาตให้ดำเนินการใด ๆ ดังนั้นในแต่ละครั้งมีเพียงหนึ่งเธรดเท่านั้นที่สามารถทำงานได้ ดังนั้นเวลาที่รอจะเพิ่มขึ้นที่นี่ เราสามารถพูดได้ว่าประสิทธิภาพค่อนข้างต่ำเมื่อคุณเปรียบเทียบกับ ConcurrentHashMap

  1. ConcurrentHashMap

มันจะรักษาล็อคที่ระดับเซกเมนต์ มันมี 16 ส่วนและรักษาระดับการทำงานพร้อมกันเป็น 16 โดยค่าเริ่มต้น ดังนั้นในแต่ละครั้งสามารถมี 16 เธรดที่สามารถทำงานบน ConcurrentHashMap ได้ นอกจากนี้การดำเนินการอ่านไม่จำเป็นต้องล็อค ดังนั้นจำนวนเธรดใด ๆ ที่สามารถทำการดำเนินการ get ได้

หาก thread1 ต้องการดำเนินการวางในส่วนที่ 2 และ thread2 ต้องการที่จะดำเนินการใส่ในส่วนที่ 4 แล้วมันได้รับอนุญาตที่นี่ หมายความว่า 16 เธรดสามารถทำการอัปเดต (วาง / ลบ) บน ConcurrentHashMap ได้ตลอดเวลา

ดังนั้นเวลาที่รอจะน้อยกว่าที่นี่ ดังนั้นประสิทธิภาพค่อนข้างดีกว่า synchronizedHashmap


คำอธิบายที่ดีมากขอบคุณมาก
amoljdv06

11

ทั้งคู่เป็นรุ่นที่ใช้งานร่วมกันของ HashMap ซึ่งมีความแตกต่างในการทำงานหลักและโครงสร้างภายในของพวกเขา

ConcurrentHashMapประกอบด้วยส่วนภายในที่สามารถดูเป็นอิสระ HashMaps Conceptually เซกเมนต์ดังกล่าวทั้งหมดสามารถล็อคโดยเธรดแยกต่างหากในการดำเนินการพร้อมกันสูง ดังนั้นหลายเธรดสามารถรับ / วางคู่คีย์ - ค่าจาก ConcurrentHashMap โดยไม่มีการบล็อก / รอกันและกัน สิ่งนี้ถูกนำไปใช้เพื่อปริมาณงานที่สูงขึ้น

แต่ทว่า

Collections.synchronizedMap ()เราได้รับ HashMap เวอร์ชันซิงโครไนซ์และเข้าถึงได้ในลักษณะการบล็อก ซึ่งหมายความว่าหากมีหลายเธรดพยายามเข้าถึง synchronMap ในเวลาเดียวกันพวกเขาจะได้รับอนุญาตให้รับ / ใส่ค่าคีย์คู่ทีละครั้งในลักษณะที่ซิงโครไนซ์


7

ConcurrentHashMapใช้กลไกการล็อคแบบละเอียดยิ่งขึ้นซึ่งเรียกว่าlock strippingการอนุญาตให้ใช้งานร่วมกันในระดับที่สูงขึ้น เนื่องจากนี้จะให้ดีกว่าที่เห็นพ้องและความยืดหยุ่น

ตัววนซ้ำที่ส่งคืนมาConcurrentHashMapนั้นมีความสอดคล้องกันอย่างอ่อนช้อยแทนที่จะเป็นเทคนิคที่ล้มเหลวอย่างรวดเร็วซึ่งใช้โดย


3

วิธีการSynchronizedMapระงับการล็อคบนวัตถุในขณะที่ConcurrentHashMapมีแนวคิดของ "ล็อคสตริป" ที่ล็อคจะถูกเก็บไว้ในถังของเนื้อหาแทน ความยืดหยุ่นและประสิทธิภาพที่เพิ่มขึ้น


2

ConcurrentHashMap:

1) แผนที่ทั้งคู่เป็นการใช้งานแบบปลอดภัยของเธรดของอินเตอร์เฟสแผนที่

2) ConcurrentHashMap ใช้งานสำหรับปริมาณงานที่สูงขึ้นในกรณีที่คาดว่าจะเกิดภาวะพร้อมกันสูง

3) ไม่มีการล็อคในระดับวัตถุ

แผนที่แฮชตรง:

1) แต่ละวิธีจะซิงโครไนซ์โดยใช้การล็อกระดับวัตถุ


1

ConcurrentHashMapอนุญาตการเข้าถึงข้อมูลพร้อมกัน แผนที่ทั้งหมดถูกแบ่งออกเป็นส่วน ๆ

อ่านการดำเนินการคือ get(Object key)ไม่ซิงโครไนซ์แม้ในระดับเซกเมนต์

แต่การดำเนินการเขียนคือ remove(Object key), get(Object key)ได้รับการล็อคในระดับส่วน มีเพียงบางส่วนของแผนที่ทั้งหมดที่ถูกล็อคเธรดอื่น ๆ ยังคงสามารถอ่านค่าจากส่วนต่าง ๆ ได้ยกเว้นล็อคหนึ่งรายการ

SynchronizedMapในอีกทางได้รับการล็อคที่ระดับวัตถุ เธรดทั้งหมดควรรอเธรดปัจจุบันโดยไม่คำนึงถึงการดำเนินการ (อ่าน / เขียน)


1

การทดสอบประสิทธิภาพการทำงานที่ง่ายสำหรับ ConcurrentHashMap VS Synchronized HashMap โฟลว์ทดสอบกำลังเรียกใช้putในหนึ่งเธรดและเรียกใช้getในสามเธรดMapพร้อมกัน ดังที่ @trshiv กล่าวว่า ConcurrentHashMap มีปริมาณงานและความเร็วที่สูงขึ้นสำหรับการอ่านที่ไม่มีการล็อก ผลลัพธ์คือเมื่อเวลาในการปฏิบัติงานสิ้นสุดลง10^7ConcurrentHashMap 2xเร็วกว่า HashMap ที่ซิงโครไนซ์


1

SynchronizedMapและConcurrentHashMapเป็นทั้งคลาสที่ปลอดภัยของเธรดและสามารถใช้ในแอปพลิเคชันแบบมัลติเธรดความแตกต่างที่สำคัญระหว่างพวกเขาคือเกี่ยวกับวิธีที่พวกเขาบรรลุความปลอดภัยของเธรด

SynchronizedMapได้รับการล็อคในอินสแตนซ์แผนที่ทั้งหมดในขณะที่ConcurrentHashMapแบ่งอินสแตนซ์แผนที่ออกเป็นหลายส่วนและทำการล็อคกับสิ่งเหล่านั้น

ป้อนคำอธิบายรูปภาพที่นี่

ป้อนคำอธิบายรูปภาพที่นี่


0

ตามเอกสารของ java

Hashtable และ Collections.synchronizedMap (ใหม่ HashMap ()) ถูกซิงโครไนซ์ แต่ ConcurrentHashMap คือ "concurrent"

คอลเลกชันที่เกิดขึ้นพร้อมกันนั้นปลอดภัยต่อเธรด แต่ไม่ได้ควบคุมโดยการล็อคการแยกเดี่ยว

ในกรณีเฉพาะของ ConcurrentHashMap จะอนุญาตการอ่านพร้อมกันจำนวนใด ๆ ได้อย่างปลอดภัยรวมถึงจำนวนที่สามารถปรับแต่งได้ของการเขียนพร้อมกัน คลาส "ที่ซิงโครไนซ์" จะมีประโยชน์เมื่อคุณต้องการป้องกันการเข้าถึงคอลเลกชันทั้งหมดผ่านการล็อกเพียงครั้งเดียว

ในกรณีอื่นที่คาดว่าจะมีหลายเธรดในการเข้าถึงคอลเล็กชันทั่วไป "รุ่นที่เกิดขึ้นพร้อมกัน" จะเป็นที่นิยมกว่า และคอลเลกชันที่ไม่ซิงโครไนซ์จะดีกว่าเมื่อคอลเลกชันใดไม่ได้แชร์หรือสามารถเข้าถึงได้ก็ต่อเมื่อมีการล็อคอื่น ๆ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.