जावा में सर्वश्रेष्ठ संगामिति सूची चुनना [बंद]


98

मेरे थ्रेड पूल में थ्रेड्स की एक निश्चित संख्या है। इन थ्रेड्स को एक साझा सूची से अक्सर लिखना और पढ़ना पड़ता है।

तो, java.util.concurrentइस मामले में कौन सी डेटा संरचना (यह बेहतर होना चाहिए एक सूची, मॉनिटर-फ्री होना चाहिए) सबसे अच्छा है?


5
यह निर्भर करता है कि आप संग्रह के साथ क्या करना चाहते हैं। मेरी ब्लॉग पोस्ट देखें (हालाँकि यह .Net के बारे में है, अवधारणाएँ समान हैं)। आप सही थ्रेड-सुरक्षित कोड के साथ लिखने में सक्षम होने की संभावना नहीं है List
SLAKs

1
अब, मैं CopyOnWriteArrayList का उपयोग कर रहा हूं , लेकिन ConcurrentModificationException अपवाद अभी भी कभी-कभी फेंका जाता है।
象嘉道

2
कृपया इस बारे में अधिक जानकारी शामिल करें कि आप संग्रह के साथ क्या कर रहे हैं ताकि लोग बेहतर उत्तर दे सकें, अन्यथा यह केवल एक अनुमान है।
Mattsh

2
ConcurrentModificationExceptionएक तुल्यकालन समस्या से नहीं आ सकते हैं; यह उदाहरण के लिए एक संग्रह के लिए एक लूप में भी उत्पन्न होता है जहां आप संग्रह से एक तत्व को हटाने की कोशिश करते हैं।
तोतो 2

1
मुझे पता है कि यह पैकेज का हिस्सा नहीं है, लेकिन क्या किसी ने कोशिश की है Vector?
पश्चिमीगंज

जवाबों:


96

बेहतर था List

केवल List में कार्यान्वयन java.util.concurrentहै CopyOnWriteArrayList । ट्रैविस वेब उल्लेख के रूप में एक सिंक्रनाइज़ सूची का विकल्प भी है।

उस ने कहा, क्या आप सुनिश्चित हैं कि आपको इसकी आवश्यकता है List? समवर्ती Queueएस और Mapएस के लिए बहुत अधिक विकल्प हैं (और आप Setएस से Mapएस बना सकते हैं ), और उन संरचनाओं को उन चीजों के कई प्रकारों के लिए सबसे अधिक समझ में आता है जिन्हें आप साझा डेटा संरचना के साथ करना चाहते हैं।

कतारों के लिए, आपके पास बड़ी संख्या में विकल्प हैं और जो सबसे उपयुक्त है, यह इस बात पर निर्भर करता है कि आपको इसका उपयोग करने की आवश्यकता है:


14
CopyOnWriteArrayListलिखने पर बहुत महंगा होने का नुकसान होता है (लेकिन सस्ते में पढ़ता है) यदि आप बहुत सारे लेखन कर रहे हैं तो आप एक सिंक्रनाइज़ सूची या कतार के साथ बेहतर हैं।
पीटर लॉरी

67

किसी भी जावा संग्रह को थ्रेड-सुरक्षित किया जा सकता है जैसे:

List newList = Collections.synchronizedList(oldList);

या एक नया थ्रेड-सुरक्षित सूची बनाने के लिए:

List newList = Collections.synchronizedList(new ArrayList());

http://download.oracle.com/javase/6/docs/api/java/util/Collections.html#synchronizedList(java.util.List)


7
इस कारण से, आपको java.util.concurrent - Uhm में कोई सूची कार्यान्वयन नहीं मिलेगा , ConcurrentHashMapएक Collections.synchronizedMapविधि होने के बावजूद भी है ।
एनियोबे

7
पर Javadocs पढ़ें ConcurrentHashMap। सिंक्रनाइज़ेशन कार्यान्वयन का विवरण अलग है। मूल रूप से सिर्फ जावा मॉनिटर में क्लास को लपेटने के synchronizedतरीकों का उपयोग करना CollectionsConcurrentHashMapअधिक चतुर संगामिति सुविधाओं का उपयोग करता है।
ट्रैविस वेब

1
हां। फिर भी, यह आपके अंतिम वाक्य को भले ही अमान्य बना देता है।
19obe को aioobe

1
उपयोग तो एक मॉनिटर, कार्यक्रम का प्रदर्शन वास्तव में बुरा है :-(
象嘉道

5
बस जोड़ने के लिए, newList पर चलना थ्रेड सुरक्षित नहीं है। !!
ब्ल्युलेरकर

9

यदि सूची का आकार यदि निश्चित है, तो आप एक AtomicReferenceArray का उपयोग कर सकते हैं । यह आपको एक स्लॉट में अनुक्रमित अपडेट करने की अनुमति देगा। यदि आवश्यक हो तो आप एक सूची दृश्य लिख सकते हैं।


6

आप पॉल मार्टिन के "ए प्रैक्टिकल लॉक-फ्री डबली-लिंक्ड लिस्ट" पर आधारित डग ले द्वारा लिखे गए समवर्तीDinklyLinkedList को देखना चाह सकते हैं । यह java.util.List इंटरफ़ेस को लागू नहीं करता है, लेकिन एक सूची में आपके द्वारा उपयोग किए जाने वाले अधिकांश तरीके प्रदान करता है।

जावदोक के अनुसार:

एक समवर्ती लिंक्ड-लिस्ट का कार्यान्वयन एक Deque (डबल-एंड क्यू)। समवर्ती सम्मिलन, हटाने और पहुंच संचालन कई थ्रेड्स में सुरक्षित रूप से निष्पादित होते हैं। Iterators कमजोर रूप से सुसंगत हैं , लौटने वाले तत्व किसी बिंदु पर या जब से पुनरावृत्तिकर्ता के निर्माण के बाद की अवस्था को दर्शाते हैं। वे ConcurrentModificationException को नहीं फेंकते हैं, और अन्य कार्यों के साथ समवर्ती रूप से आगे बढ़ सकते हैं।


5

ConcurrentLinkedQueueलॉक-फ्री कतार (नए CAS निर्देश के आधार पर ) का उपयोग करता है।


7
... जो Listइंटरफ़ेस को लागू नहीं करता है।
एनियोबे

1
eSniff, आप List.set(int index, Object element)ConcurrentLinkedQueue के साथ कैसे लागू करेंगे?
जॉन विंट

4
अधिकांश- Listविशिष्ट तरीके या तो लागू नहीं होने जा रहे हैं Queue(उदाहरण के लिए, एक विशिष्ट सूचकांक में / सेट जोड़ें) या कार्यान्वित किया जा सकता है, लेकिन अक्षम (एक सूचकांक से प्राप्त) होगा। इसलिए मुझे नहीं लगता कि आप वास्तव में इसे लपेट सकते हैं। मैंने कहा, मुझे लगता है कि एक का सुझाव Queueठीक है क्योंकि ओपी ने वास्तव में नहीं बताया है कि उन्हें इसकी आवश्यकता क्यों है List
कॉलिनड

1
@ColinD कि जवाब मैं के लिए जा रहा था। CLQ को लिस्ट में लपेटा नहीं जा सकता, इसके अच्छे कारण हैं। हालांकि मैं सहमत हूं, क्यू इंटरफ़ेस को खारिज नहीं कर सकता।
जॉन विंट

1
❗️ वर्थ नोटिंग: "सावधान रहें कि, अधिकांश संग्रहों के विपरीत, आकार विधि एक निरंतर-समय का संचालन नहीं है। इन कतारों की अतुल्यकालिक प्रकृति के कारण, तत्वों की वर्तमान संख्या का निर्धारण करने के लिए तत्वों की एक त्रिकोणीय आवश्यकता होती है।"
बेहरंग सईदज़ादेह

3

यदि सेट पर्याप्त है, तो समवर्तीSkipListSet का उपयोग किया जा सकता है। (इसका कार्यान्वयन समवर्तीSkipListMap पर आधारित है जो एक स्किप सूची लागू करता है ।)

अपेक्षित औसत समय लागत में शामिल, संचालन को हटाने और हटाने के लिए लॉग (n) है; आकार विधि एक निरंतर-समय ऑपरेशन नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.