2009-08-13 19 views
7

संभव डुप्लिकेट:
Is the C# static constructor thread safe?स्टेटिक प्रारंभिक सिंगलटन थ्रेड सुरक्षा की गारंटी देता है? (सी #)

http://csharpindepth.com/Articles/General/Singleton.aspx पर

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

हालांकि, अधिकांश लोग सहमत हैं (श्री स्कीट सहित, उनके लेख में चार और पांच नमूने में), स्थिर प्रारंभिक उपयोग का उपयोग है थ्रेडसेफ सिंगलटन उदाहरण प्राप्त करने का एक आसान तरीका। वह कहता है कि "सी # में स्थैतिक रचनाकार केवल तभी निष्पादित करने के लिए निर्दिष्ट किए जाते हैं जब कक्षा का एक उदाहरण बनाया जाता है या एक स्थिर सदस्य का संदर्भ दिया जाता है, और प्रति एपडोमेन में केवल एक बार निष्पादित किया जाता है।"

यह समझ में आता है, लेकिन जो गुम हो रहा है वह गारंटी है कि नए ऑब्जेक्ट का संदर्भ केवल कन्स्ट्रक्टर पूरा होने के बाद ही सौंपा गया है - अन्यथा हमें एक ही तरह का मुद्दा मिल जाएगा जो डबल-चेक लॉकिंग विफल करता है आप आवृत्ति को अस्थिर के रूप में चिह्नित करते हैं। क्या कोई गारंटी है कि, इंस्टेंस कन्स्ट्रक्टर को कॉल करने के लिए स्थिर प्रारंभिकरण का उपयोग करते समय (एक प्रॉपर्टी के प्राप्त होने वाले इंस्टेंस कन्स्ट्रक्टर को कॉल करने के विपरीत {}, जैसे कि हम डबल-चेक लॉकिंग के साथ करते हैं), कि कन्स्ट्रक्टर किसी अन्य थ्रेड से पहले पूरी तरह से पूरा हो जाएगा वस्तु का संदर्भ प्राप्त कर सकते हैं?

धन्यवाद!

+0

(टिप्पणी का जवाब दिया) –

उत्तर

2

हां; गारंटी इस कथन में है कि यह प्रति ऐपडोमेन में केवल एक बार निष्पादित होगी।

यह केवल असुरक्षित हो सकता है अगर यह एक से अधिक बार निष्पादित हो सकता है; जैसा कि कहा गया है, यह नहीं कर सकता है, तो सब ठीक है :)

9

कि किसी भी अन्य थ्रेड ऑब्जेक्ट का संदर्भ प्राप्त करने से पहले निर्माता पूरी तरह से पूरा हो जाएगा?

स्थिर प्रारंभकर्ता AppDomain प्रति (कम से कम, प्रणाली द्वारा) केवल एक बार लागू किया जाएगा, और एक तुल्यकालन तरह से, ले रही है "beforefieldinit" खाते में। तो मान लीजिए कि आप कुछ भी विचित्र नहीं करते हैं, स्थैतिक प्रारंभकर्ता में असाइन किए गए किसी स्थिर क्षेत्र को ठीक होना चाहिए; स्थैतिक क्षेत्र का उपयोग करने के किसी अन्य प्रयास को स्थैतिक कन्स्ट्रक्टर के पीछे (अवरुद्ध) होना चाहिए।

नई वस्तु के संदर्भ में सौंपा के बाद ही निर्माता पूरा करता

यह तब होता है जब ऐसा होता है है। से पहले कोई भी स्थिर क्षेत्र प्रारंभकर्ता होता है, उदाहरण के लिए आप आमतौर पर निर्माता के रूप में क्या सोचते हैं। लेकिन चूंकि अन्य धागे अवरुद्ध हैं, यह एक मुद्दा नहीं होना चाहिए।

हालांकि

:

  • अगर आपके स्थिर प्रारंभकर्ता ही बाहर एक संदर्भ से गुजरता है (एक तर्क के रूप संदर्भ में एक विधि को फोन करके ("arg0" सहित), तो सभी दांव बंद कर रहे हैं
  • अगर आप स्थिर निर्माता आह्वान करने के लिए प्रतिबिंब का उपयोग (हाँ, आप ऐसा कर सकते हैं), crazyness अक्सर इस प्रकार
+0

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

+0

2: हाँ; जब तक यह स्थैतिक .cctor के अंदर होता है, तब तक अन्य धागे अवरुद्ध किए जाने चाहिए। wrt उदाहरण रचनाकार ... निर्माण के दौरान 2 धागे एक उदाहरण के साथ कैसे बात कर सकते हैं? –

+0

मेरे हिस्से पर बुरा उदाहरण। यहां तीसरा नमूना देखें: http://msdn.microsoft.com/en-us/library/ms998558.aspx। जब तक आप "इंस्टेंस" अस्थिर सेट नहीं करते हैं, यह संभव है कि कंपाइलर कन्स्ट्रक्टर को रेखांकित करता है, और ऑब्जेक्ट का निर्माण करने से पहले "इंस्टेंस" नामक वेरिएबल * संदर्भ प्राप्त कर सकता है। एक और धागा इस उदाहरण को पकड़ सकता है, जिससे डबल-चेक की पहली जांच झूठी वापसी के लिए होती है, और तब वह धागा एक असंवैधानिक उदाहरण का उपयोग कर समाप्त हो सकता है। मैं यह निर्धारित करने की कोशिश कर रहा हूं कि टाइप प्रारंभिकरण का उपयोग करने का सरल कार्य पूरी तरह से, या ऐसा कुछ होने से रोकता है। –

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