दिलचस्प पोस्ट
आईओएस 7 कस्टम बैक बटन शेल स्क्रिप्ट में बूलीयन वैरिएबल कैसे घोषित और उपयोग करें? तीन। जेएस यूवी समन्वय उत्पन्न करते हैं Laravel आदेश एक रिश्ते पर पहचान द्वारा किसी वस्तु को संदर्भित करने का मानक तरीका (के लिए, उदाहरण के लिए, परिपत्र संदर्भ)? उच्चचर्च – पूर्ण चार्ट चौड़ाई के बारे में मुद्दा सी # संपत्ति के लघुकोड के VB.NET बराबर? दो जावास्क्रिप्ट वस्तुओं के लिए समानता कैसे निर्धारित करें? मैं ट्यूपल को विविधतापूर्ण टेम्पलेट फंक्शन के तर्कों में कैसे विस्तारित करूं? JqGrid में जोड़ें / संपादित करें संवाद को कस्टमाइज़ करना एंड्रॉइड स्टूडियो में एक लाइब्रेरी प्रोजेक्ट और लायब्रेरी प्रोजेक्ट का उपयोग करने वाले एक एप्लिकेशन प्रोजेक्ट को कैसे तैयार किया जाए JQuery का उपयोग करते हुए मैं एक टेक्स्टबॉक्स का मान कैसे प्राप्त करूं? JQuery के datepicker के साथ विशिष्ट श्रेणी में दिनांक हाइलाइट करें फ्रेगमेंट में एंड्रॉइड साझा किए गए संदर्भ कैफ में `lr_policy` क्या है?

सी # स्थिर निर्माता थ्रेड सुरक्षित है?

दूसरे शब्दों में, यह सिंगलटन कार्यान्वयन थ्रेड सुरक्षित है:

public class Singleton { private static Singleton instance; private Singleton() { } static Singleton() { instance = new Singleton(); } public static Singleton Instance { get { return instance; } } } 

Solutions Collecting From Web of "सी # स्थिर निर्माता थ्रेड सुरक्षित है?"

स्टेटिक कन्स्ट्रक्शर्स की गारंटी है कि प्रत्येक डोमेन के किसी भी उदाहरण के पहले ही किसी भी अनुप्रयोग डोमेन में एक बार चलाया जा सकता है या किसी भी स्थैतिक सदस्य तक पहुंचना है। http://msdn.microsoft.com/en-us/library/aa645612.aspx

दिखाया गया कार्यान्वयन प्रारंभिक निर्माण के लिए धागा सुरक्षित है, अर्थात, सिंगलटन ऑब्जेक्ट के निर्माण के लिए कोई लॉकिंग या रिक्त परीक्षण आवश्यक नहीं है। हालांकि, इसका यह अर्थ नहीं है कि उदाहरण के किसी भी उपयोग को सिंक्रनाइज़ किया जाएगा। कई तरह के तरीकों से यह किया जा सकता है; मैंने नीचे एक दिखाया है I

 public class Singleton { private static Singleton instance; // Added a static mutex for synchronising use of instance. private static System.Threading.Mutex mutex; private Singleton() { } static Singleton() { instance = new Singleton(); mutex = new System.Threading.Mutex(); } public static Singleton Acquire() { mutex.WaitOne(); return instance; } // Each call to Acquire() requires a call to Release() public static void Release() { mutex.ReleaseMutex(); } } 

हालांकि इन उत्तरों में से सभी एक ही सामान्य जवाब दे रहे हैं, एक चेतावनी है

याद रखें कि एक जेनेरिक क्लास के सभी संभावित व्युत्पन्न व्यक्तिगत प्रकार के रूप में संकलित किए जाते हैं। इसलिए जेनेरिक प्रकारों के लिए स्थिर कन्स्ट्रक्टर को लागू करते समय सावधानी बरतें।

 class MyObject<T> { static MyObject() { //this code will get executed for each T. } } 

संपादित करें:

यहां प्रदर्शन किया गया है:

 static void Main(string[] args) { var obj = new Foo<object>(); var obj2 = new Foo<string>(); } public class Foo<T> { static Foo() { System.Diagnostics.Debug.WriteLine(String.Format("Hit {0}", typeof(T).ToString())); } } 

कंसोल में:

 Hit System.Object Hit System.String 

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

सी # भाषा विनिर्देश से http://msdn.microsoft.com/en-us/library/aa645612(VS.71).aspx :

एक क्लास के लिए स्थिर निर्माता एक दिए गए एप्लिकेशन डोमेन में सबसे अधिक बार कार्यान्वित करता है। एक स्थैतिक निर्माता का निष्पादन एक अनुप्रयोग डोमेन के भीतर आने के लिए निम्नलिखित घटनाओं की पहली शुरुआत है:

  • क्लास का एक उदाहरण बनाया गया है।
  • वर्ग के स्थैतिक सदस्यों में से कोई भी संदर्भित है

तो हाँ, आप इस बात पर भरोसा कर सकते हैं कि आपका सिंगलटन सही ढंग से तत्काल होगा।

ज़ोबा ने एक उत्कृष्ट बिंदु बनाया (और मेरे 15 सेकंड पहले भी!) कि स्थिर निर्माता सिंगलटन के लिए धागा-सुरक्षित साझा पहुंच की गारंटी नहीं देगा। उसे दूसरे तरीके से संभालना होगा

सी # सिंगलटन पर ऊपर एमएसडीएन पृष्ठ से क्लिफनॉट्स संस्करण है:

निम्न पैटर्न का प्रयोग करें, हमेशा, आप गलत नहीं जा सकते हैं:

 public sealed class Singleton { private static readonly Singleton instance = new Singleton(); private Singleton(){} public static Singleton Instance { get { return instance; } } } 

स्पष्ट सिंगलटन सुविधाओं के अलावा, यह आपको इन दो चीजों को मुफ्त में देता है (सिंगलटन के संदर्भ में सी ++):

  1. आलसी निर्माण (या कोई निर्माण अगर यह कभी नहीं कहा गया था)
  2. तुल्यकालन

स्टेटिक कन्स्ट्रक्टर को ऐप डोमेन प्रति केवल एक बार आग लगाने की गारंटी है ताकि आपका दृष्टिकोण ठीक हो। हालांकि, यह कार्यात्मक रूप से अधिक संक्षिप्त, इनलाइन संस्करण से अलग नहीं है:

 private static readonly Singleton instance = new Singleton(); 

थ्रेड सुरक्षा एक समस्या का अधिक है जब आप चीजें कमजोर कर रहे हैं

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

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

जैसा कि ज़ूमबा का जवाब बताता है आपको एकाधिक थ्रेड्स से एक्सेस करने के लिए सिंगलटन सुरक्षित बनाने की आवश्यकता होगी, या सिंगलटन इंस्टेंस का प्रयोग करने के दौरान लॉकिंग तंत्र को लागू करना होगा।

सिर्फ पंडिताऊ होने के लिए, लेकिन स्थिर निर्माता के रूप में ऐसी कोई चीज नहीं है, बल्कि स्थिर प्रकार के शुरुआती, यहां चक्रीय स्थैतिक निर्माता निर्भरता का एक छोटा डेमो है जो इस बिंदु को दिखाता है।

स्टेटिक कन्स्ट्रक्टर को थ्रेड सुरक्षित होने की गारंटी है। इसके अलावा, डेवलपर ज़ेन पर सिंगलटन पर चर्चा देखें : http://www.developerzen.com/2007/07/15/whats-wrong-with-this-code-1-discussion/

किसी भी थ्रेड को कक्षा तक पहुंचने के लिए अनुमति देने से पहले स्थिर निर्माता का चलना खत्म हो जाएगा।

  private class InitializerTest { static private int _x; static public string Status() { return "_x = " + _x; } static InitializerTest() { System.Diagnostics.Debug.WriteLine("InitializerTest() starting."); _x = 1; Thread.Sleep(3000); _x = 2; System.Diagnostics.Debug.WriteLine("InitializerTest() finished."); } } private void ClassInitializerInThread() { System.Diagnostics.Debug.WriteLine(Thread.CurrentThread.GetHashCode() + ": ClassInitializerInThread() starting."); string status = InitializerTest.Status(); System.Diagnostics.Debug.WriteLine(Thread.CurrentThread.GetHashCode() + ": ClassInitializerInThread() status = " + status); } private void classInitializerButton_Click(object sender, EventArgs e) { new Thread(ClassInitializerInThread).Start(); new Thread(ClassInitializerInThread).Start(); new Thread(ClassInitializerInThread).Start(); } 

उपरोक्त कोड नीचे दिए गए परिणामों का उत्पादन किया।

 10: ClassInitializerInThread() starting. 11: ClassInitializerInThread() starting. 12: ClassInitializerInThread() starting. InitializerTest() starting. InitializerTest() finished. 11: ClassInitializerInThread() status = _x = 2 The thread 0x2650 has exited with code 0 (0x0). 10: ClassInitializerInThread() status = _x = 2 The thread 0x1f50 has exited with code 0 (0x0). 12: ClassInitializerInThread() status = _x = 2 The thread 0x73c has exited with code 0 (0x0). 

यद्यपि स्थिर निर्माता ने चलाने के लिए लंबा समय लगा, अन्य धागे बंद कर दिए और इंतजार किया। सभी थ्रेड्स स्थिर निर्माता के नीचे _x सेट के मान को पढ़ते हैं।

हालांकि अन्य उत्तर अधिकतर सही हैं, स्थिर कन्स्ट्रक्टर के साथ एक और चेतावनी है।

अनुभाग II.10.5.3.3 के अनुसार, ECMA-335 कॉमन लैंग्वेज इन्फ्रास्ट्रक्चर के रेस और डेडलॉक

केवल प्रारंभिकरण टाइप ही एक गतिरोध नहीं बनाएगा, जब तक कि किसी प्रकार के प्रारंभ initializer (प्रत्यक्ष या अप्रत्यक्ष रूप से) से बुलाए गए कोड स्पष्ट रूप से ब्लॉकिंग ऑपरेशन को आमंत्रित करता है।

डेडलॉक में निम्नलिखित कोड का परिणाम है

 using System.Threading; class MyClass { static void Main() { /* Won't run... the static constructor deadlocks */ } static MyClass() { Thread thread = new Thread(arg => { }); thread.Start(); thread.Join(); } } 

मूल लेखक इगोर ओस्ट्रोवस्की है, यहां उनकी पोस्ट देखें।