2009-04-01 12 views
42

निम्नलिखित साइट से:सूची <T> क्यों धागा-सुरक्षित नहीं है?

http://crfdesign.net/programming/top-10-differences-between-java-and-c

दुर्भाग्य से, List<> थ्रेड-सुरक्षित नहीं है (सी # के ArrayList और जावा के Vector धागा सुरक्षित हैं)। सी # में Hashtable भी है; सामान्य संस्करण है:

List<T> क्या थ्रेड-सुरक्षित नहीं बनाता है? क्या यह .NET फ्रेमवर्क इंजीनियर के हिस्से पर कार्यान्वयन समस्या है? या जेनेरिक थ्रेड-सुरक्षित नहीं हैं?

+0

उपयोग करने के लिए MSDN [ArrayList] (http://msdn.microsoft.com/en-us/library/system.collections के अनुसार प्रदान करता है। arraylist.aspx # threadSafetyToggle) और [सूची (टी का)] (http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx#threadSafetyToggle) एक ही थ्रेड सुरक्षा है। 'ArrayList' [सिंक्रनाइज़] प्रदान करता है (http://msdn.microsoft.com/en-us/library/system.collections.arraylist.synchronized.aspx) रैपर हालांकि। –

उत्तर

67

आपको वास्तव में जावा के वेक्टर के थ्रेड सुरक्षा को वर्गीकृत करने की आवश्यकता है। जावा वेक्टर कई धागे से उपयोग किया जा सकता है क्योंकि यह विधियों पर सिंक्रनाइज़ेशन का उपयोग करता है। राज्य दूषित नहीं होगा।

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

Vector vector = getVector(); 
if (vector.size() > 0) { 
    object first = vector.get(0); 
} 

से एक तत्व पढ़ने के सरल कार्य पर विचार करें, लेकिन यह भी सही नहीं है। यदि कथन() कॉल के बीच वेक्टर को म्यूट करने से दूसरे धागे को रोकना कुछ भी नहीं है। यह कोड अंततः दौड़ की स्थिति के कारण विफल हो सकता है।

इस प्रकार का सिंक्रनाइज़ेशन केवल कुछ हद तक परिदृश्यों में उपयोगी है और यह निश्चित रूप से सस्ता नहीं है। यदि आप एकाधिक धागे का उपयोग नहीं करते हैं तो भी आप सिंक्रनाइज़ेशन के लिए एक उल्लेखनीय मूल्य का भुगतान करते हैं।

.Net ने केवल सीमित उपयोगिता के परिदृश्य के लिए डिफ़ॉल्ट रूप से इस कीमत का भुगतान नहीं करना चुना। इसके बजाए इसे लॉक फ्री लिस्ट को लागू करना चुना गया। लेखक किसी भी सिंक्रनाइज़ेशन को जोड़ने के लिए ज़िम्मेदार हैं। यह सी ++ के मॉडल के करीब है "आप जो भी उपयोग करते हैं उसके लिए भुगतान करें"

मैंने हाल ही में जावा के वेक्टर जैसे आंतरिक सिंक्रनाइज़ेशन के साथ संग्रह का उपयोग करने के खतरों पर कुछ लेख लिखे हैं।

संदर्भ वेक्टर धागा सुरक्षा: http://www.ibm.com/developerworks/java/library/j-jtp09263.html

+13

छोटा नोट: "लॉक फ्री" का अर्थ है "बिना किसी ताले के सिंक्रनाइज़", "कोई ताला नहीं"। http://en.wikipedia.org/wiki/Lock_free –

+0

मैं स्ट्रिलैंक के साथ सहमत हूं: मुझे "लॉक फ्री" शब्दावली का उपयोग करने के लिए डबल-लेना पड़ा। –

+0

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

20

क्यों यह थ्रेड-सुरक्षित होगा? हर वर्ग नहीं है। वास्तव में, डिफ़ॉल्ट रूप से, कक्षाएं थ्रेड-सुरक्षित नहीं हैं।

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

9

यह बस प्रकार लागू करने के लिए सुरक्षित थ्रेड नहीं एक डिजाइन निर्णय है। संग्रह डेटा प्रकारों को स्पष्ट रूप से सिंक्रनाइज़ करने के लिए कुछ संग्रहों पर इंटरफ़ेस ICollection और Synchronized() विधि की संपत्ति SyncRoot प्रदान करता है।

मल्टीथ्रेड किए गए वातावरण में किसी ऑब्जेक्ट को लॉक करने के लिए SyncRoot का उपयोग करें।

lock (collection.SyncRoot) 
{ 
    DoSomething(collection); 
} 

उपयोग collection.Synchronized() संग्रह के लिए एक धागा सुरक्षित आवरण प्राप्त करने के लिए।

+4

जेरेडपार के लेखों को एक स्पष्टीकरण के लिए देखें कि यह लगभग निश्चित रूप से क्यों नहीं है जो आप करना चाहते हैं। –

2

सच धागा सुरक्षा के लिए, List<> और अन्य संग्रह प्रकारों को अपरिवर्तनीय होने की आवश्यकता होगी। .NET 4.0 में .NET के समानांतर एक्सटेंशन के साथ हम सबसे अधिक उपयोग किए जाने वाले संग्रहों के थ्रेड सुरक्षित संस्करण देखेंगे। Jon Skeet इनमें से कुछ पर छूता है।

2

रेस-हालत की संभावना जेरेडपार का उल्लेख वेक्टर की थ्रेड-सुरक्षा पर भरोसा करने का डरावना परिणाम है। यह ऐसी चीज है जिसके परिणामस्वरूप "प्रत्येक नौवीं मंगलवार ऐप कुछ अजीब करता है" - दोष रिपोर्ट की रिपोर्ट जो आपको पागल कर देगी।

सही मायने में धागे की सुरक्षित संग्रह coming in .Net 4 के एक नंबर, एक दिलचस्प पक्ष प्रभाव के साथ कि वे एकल पिरोया modification of the collection while enumerating की अनुमति देते हैं, लेकिन वहाँ एक performance hit कि धागे की सुरक्षा, कभी कभी एक बहुत बड़ी एक के साथ आता है।

तो एक फ्रेमवर्क डेवलपर के लिए तार्किक चीज कक्षा को 9 5% उपयोगकर्ताओं के लिए जितना संभव हो उतना प्रदर्शन करने वाला है, जो शायद थ्रेडिंग नहीं कर पाएंगे और उन लोगों पर भरोसा करेंगे जो उनके पास हैं इसे सुरक्षित रखने के लिए करने के लिए।

0

उपयोग SynchronizedCollection यह भी एक निर्माता-पैरामीटर एक साझा सिंक :)

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