2012-01-23 16 views
31

मान लीजिए कि मेरे पास डेटा की एक सरणी है, क्या 2 थ्रेड एक ही सरणी के अलग-अलग इंडेक्स को सुरक्षित रूप से लिख सकते हैं? मैं लिखने की गति के बारे में चिंतित हूं, और मैं वास्तविक लेखन बनाम 'लिखने के लिए सूचकांक' को सिंक्रनाइज़ करना चाहता हूं।जावा समेकन - एक ही सरणी के विभिन्न इंडेक्स को लिखना

मैं कोड लिख रहा हूं जो मुझे लगता है कि 2 धागे एक ही सूचकांक प्राप्त नहीं करेंगे।

+4

क्या एक धागा इंडेक्स * i * और अन्य सूचकांक * i * से पढ़ेगा? – aioobe

+0

आप किस प्रकार की सरणी कक्षा का उपयोग कर रहे हैं इस पर निर्भर करता है। क्या आप अधिक जानकारी प्रदान कर सकते हैं? – Michael

+0

मदद के लिए धन्यवाद, सब कुछ। –

उत्तर

33

एक सरणी में दो अलग-अलग इंडेक्स के लिए एक ही नियम दो अलग-अलग चर के लिए लागू होते हैं।

जावा भाषा विशिष्टता में अध्याय "Threads and Locks" बताते हुए से शुरू होता है:

17.4.1 साझा चर

[...]

सभी दृष्टांत फ़ील्ड, स्थिर क्षेत्रों और सरणी तत्व ढेर स्मृति में संग्रहीत हैं। इस अध्याय में, हम शब्द फ़ील्ड और सरणी तत्वों दोनों को संदर्भित करने के लिए चर शब्द का उपयोग करते हैं।

इसका मतलब है कि आप दो अलग-अलग इंडेक्स को सुरक्षित रूप से लिख सकते हैं। हालांकि आपको एक ही इंडेक्स को लिखना/पढ़ना सिंक्रनाइज़ करना होगा यदि आप यह सुनिश्चित करना चाहते हैं कि उपभोक्ता थ्रेड निर्माता थ्रेड द्वारा लिखे गए अंतिम मूल्य को देखे।

+2

+1। –

+0

बहुत बढ़िया जानकारी। यहां गॉचाचा है: क्या जावा कार्यान्वयन हैं जो spec के इस हिस्से का पालन नहीं करते हैं? – TreyE

+3

नहीं, क्योंकि यह जावा कार्यान्वयन के रूप में नहीं गिना जाएगा, है ना? :) – aioobe

11

दो अलग-अलग धागे में दो अलग-अलग चर संशोधित करना सुरक्षित है। सरणी में दो अलग-अलग तत्वों को संशोधित करने के लिए कम से कम जहां तक ​​ओएस का संबंध है, अलग-अलग मेमोरी पतों के तहत दो अलग-अलग चर को संशोधित करने के लिए तुलना की जा सकती है। तो हाँ, यह सुरक्षित है।

0

CopyOnWriteArrayList पर एक नज़र डालें, बशर्ते आप एक सरणी सूची के साथ ठीक हो। इसके प्रलेखन, से

ArrayList का एक धागा सुरक्षित प्रकार, जिसमें सभी mutative संचालन (जोड़, सेट, और इतने पर) अंतर्निहित सरणी के एक ताजा प्रतिलिपि बनाकर लागू किया जाता है।

यह आमतौर पर बहुत महंगी है, लेकिन जब बेहद म्यूटेशन संख्या से बढ़ना ट्रेवर्सल संचालन, और उपयोगी है विकल्प तुलना में अधिक कुशल हो सकता है जब आप या नहीं कर सकते हैं traversals सिंक्रनाइज़, फिर भी समवर्ती धागे के बीच हस्तक्षेप बाधा की जरूरत नहीं करना चाहते ।

और

CopyOnWriteArrayList का एक उदाहरण एक सूची कार्यान्वयन के रूप में व्यवहार कई समवर्ती पढ़ता है की अनुमति देता है कि, और के लिए एक लिखने के साथ समवर्ती होने के लिए पढ़ता है। जिस तरह से यह हर बार सूची में एक नई नई प्रतिलिपि बनाना है, इसे बदल दिया जाता है।

पढ़ता है ब्लॉक को प्रभावी रूप से केवल अस्थिर पढ़ने की लागत का भुगतान नहीं करता है; लिखते हैं (या इसके विपरीत) ब्लॉक को अवरुद्ध नहीं करते हैं, लेकिन केवल एक ही लेखन एक ही समय में हो सकता है।

+3

क्या आप उसे हर बार एक मूल्य लिखते समय पूरी डेटा संरचना की एक प्रति बनाने की सलाह देते हैं ?! जेएलएस से उद्धरण के लिए – aioobe

1

वैसे हाँ यह तकनीकी रूप से सच है, लेकिन इस जवाब में इतनी सारी चेतावनी हैं कि यह आपको हां बताने के लिए बहुत चिंतित है। क्योंकि जब आप किसी सरणी में दो अलग-अलग स्थानों पर लिख सकते हैं तो आप समवर्ती मुद्दों में भाग लेने के बिना और कुछ नहीं कर सकते हैं। असली सवाल यह आता है कि आप क्या कर रहे हैं यदि आप ऐसा कर सकते हैं?

यदि आपके पास अलग-अलग स्थानों पर लिखे गए सरणी के रूप में स्थानांतरित चर काउंटर थे, तो आप समवर्ती मुद्दों में भाग सकते हैं। यह संभव है कि जैसे ही आपकी सरणी भर जाती है, आपके पास दो धागे हो सकते हैं और उसी स्थान पर लिख सकते हैं। यदि आपके पास संभावित रूप से सरणी का पाठक था जो उसी स्थान को पढ़ सकता है जिसे लिखा जा रहा है तो आपके पास समवर्ती समस्याएं होंगी। लिखने के अलावा कुछ भी नहीं करता है अगर आप इसे वापस पढ़ने की योजना नहीं बनाते हैं, तो मुझे लगता है कि जब आप पाठक को जोड़ने के लिए जाते हैं तो आपको समवर्ती समस्याएं होती हैं (जो आपके लेखकों को लॉक करना होगा)। फिर सवाल यह है कि क्या आप स्थानांतरित नहीं करते हैं, जहां थ्रेड लिखते हैं जो इसे डेटा पर लिखने से रोकता है? और यदि आप कभी भी उस धागे को नहीं ले जाते जहां थ्रेड लिखता है कि आप सरणी का उपयोग क्यों कर रहे हैं? बस उन्हें लिखने के लिए अलग-अलग अक्षरों या चर के दिए गए, और वास्तव में उन्हें अलग रखें।

अपने इरादों की पूरी तस्वीर के बिना "हां" आपको बिना किसी सोच के खतरे में ले जा सकता है कि आप ऐसा क्यों कर रहे हैं जो आप कर रहे हैं।

+3

उनके पास कई "लेखक" धागे हो सकते हैं जो समवर्ती रूप से सरणी के गैर ओवरलैपिंग भागों को लिखते हैं और एक बार सब खत्म हो जाते हैं, सबकुछ लिखा जाता है। तब कोई बढ़िया सिंक्रनाइज़ेशन की आवश्यकता नहीं है। – Alpedar

संबंधित मुद्दे