เธรดพูลของฉันมีจำนวนเธรดคงที่ เธรดเหล่านี้จำเป็นต้องเขียนและอ่านจากรายการที่แชร์บ่อยๆ
ดังนั้นโครงสร้างข้อมูลใด (ควรเป็นรายการที่ดีกว่าต้องไม่มีการมอนิเตอร์) ในjava.util.concurrent
แพ็คเกจจึงดีที่สุด
เธรดพูลของฉันมีจำนวนเธรดคงที่ เธรดเหล่านี้จำเป็นต้องเขียนและอ่านจากรายการที่แชร์บ่อยๆ
ดังนั้นโครงสร้างข้อมูลใด (ควรเป็นรายการที่ดีกว่าต้องไม่มีการมอนิเตอร์) ในjava.util.concurrent
แพ็คเกจจึงดีที่สุด
ConcurrentModificationException
อาจได้มาจากปัญหาการประสาน; นอกจากนี้ยังเกิดขึ้นตัวอย่างเช่นในการวนซ้ำบนคอลเลกชันที่คุณพยายามลบองค์ประกอบออกจากคอลเลกชัน
Vector
หรือยัง?
คำตอบ:
จะดีกว่า
List
เพียง List
การดำเนินการในการjava.util.concurrent
เป็นCopyOnWriteArrayList นอกจากนี้ยังมีตัวเลือกของรายการที่ซิงโครไนซ์ตามที่ Travis Webb กล่าวถึง
ที่กล่าวมาคุณแน่ใจหรือว่าต้องการให้เป็นList
? มีตัวเลือกมากขึ้นสำหรับQueue
s และ s พร้อมกันMap
(และคุณสามารถสร้างSet
s จากMap
s ได้) และโครงสร้างเหล่านั้นมักจะเหมาะสมที่สุดสำหรับสิ่งต่างๆหลายประเภทที่คุณต้องการทำกับโครงสร้างข้อมูลที่แชร์
สำหรับคิวคุณมีตัวเลือกมากมายและตัวเลือกใดเหมาะสมที่สุดขึ้นอยู่กับว่าคุณต้องใช้อย่างไร:
CopyOnWriteArrayList
มีข้อเสียคือค่าเขียนแพงมาก (แต่ราคาถูกสำหรับการอ่าน) หากคุณเขียนจำนวนมากคุณควรใช้รายการที่ซิงโครไนซ์หรือคิว
คอลเลกชัน Java ใด ๆ สามารถทำให้เธรดปลอดภัยได้ดังนี้:
List newList = Collections.synchronizedList(oldList);
หรือสร้างรายการที่ปลอดภัยสำหรับเธรดใหม่ล่าสุด:
List newList = Collections.synchronizedList(new ArrayList());
ConcurrentHashMap
แม้ว่าจะมีCollections.synchronizedMap
วิธีการ
ConcurrentHashMap
บน รายละเอียดของการดำเนินการซิงโครไนซ์แตกต่างกัน โดยใช้synchronized
วิธีการCollections
โดยทั่วไปเพียงแค่ห่อคลาสในจอภาพ Java ConcurrentHashMap
ใช้คุณสมบัติการทำงานพร้อมกันที่ชาญฉลาดยิ่งขึ้น
ConcurrentLinkedQueue
ใช้คิวที่ไม่มีการล็อก (ตามคำแนะนำ CAS ที่ใหม่กว่า)
List
อินเทอร์เฟซ
List.set(int index, Object element)
อย่างไรกับ ConcurrentLinkedQueue
List
วิธีการเฉพาะส่วนใหญ่จะไม่สามารถนำไปใช้งานได้โดยใช้Queue
(เช่นเพิ่ม / ตั้งค่าที่ดัชนีเฉพาะ) หรือสามารถจัดเรียงได้ แต่จะไม่มีประสิทธิภาพ (รับจากดัชนี) ฉันไม่คิดว่าคุณจะห่อได้จริงๆ ที่กล่าวว่าฉันคิดว่าคำแนะนำของ a Queue
นั้นดีเนื่องจาก OP ไม่ได้อธิบายจริงๆว่าทำไมพวกเขาถึงต้องการไฟล์List
.
คุณอาจต้องการดูConcurrentDoublyLinkedListเขียนโดย Doug Lea จาก "A Practical Lock-Free Doubly-Linked List" ของ Paul Martin ไม่ใช้อินเทอร์เฟซ java.util.List แต่มีวิธีการส่วนใหญ่ที่คุณจะใช้ในรายการ
ตาม javadoc:
การใช้งานรายการที่เชื่อมโยงพร้อมกันของ Deque (คิวสิ้นสุดสองครั้ง) การแทรกการลบและการเข้าถึงพร้อมกันจะดำเนินการอย่างปลอดภัยในหลายเธรด ตัวทำซ้ำมี ความสอดคล้องกันเล็กน้อยโดยส่งคืนองค์ประกอบที่สะท้อนสถานะของ deque ณ จุดใดจุดหนึ่งหรือตั้งแต่การสร้างตัววนซ้ำ พวกเขาไม่โยน ConcurrentModificationException และอาจดำเนินการควบคู่ไปกับการดำเนินการอื่น ๆ
หากตั้งค่าไว้เพียงพออาจใช้ConcurrentSkipListSet (การใช้งานจะขึ้นอยู่กับConcurrentSkipListMapซึ่งใช้ข้ามรายการ )
ต้นทุนเวลาเฉลี่ยที่คาดไว้คือ log (n) สำหรับการดำเนินการมีเพิ่มและลบ วิธีการกำหนดขนาดไม่ใช่การดำเนินการตลอดเวลา
List
.