2009-04-22 13 views
11

मैं हाल ही में एक साक्षात्कार में था और तकनीकी लड़के ने मुझे एक आवेदन थ्रेड-सुरक्षित बनाने के बारे में पूछा।थ्रेड सुरक्षा ऑब्जेक्ट - स्थिर या नहीं?

ठीक है, lock() सही ढंग से समझाते हुए, उन्होंने कहा कि वस्तु को स्थैतिक मानना ​​अच्छा नहीं है।

private static readonly object _syncLock = new object(); 

उन्होंने दावा किया कि कारण यह है कि स्थैतिक उस वस्तु को धागे के लिए धीमा कर देता है अगर यह स्थिर नहीं है। क्या ये सच है?

संपादित करें: फिर भी मुझे अभी भी यकीन नहीं है। इन तीन दृष्टिकोणों के बीच क्या अंतर है?

private static readonly object _syncLock = new object(); 
public static readonly object _syncLock = new object(); 
private readonly object _syncLock = new object(); 

उत्तर

12

यदि लॉक ऑब्जेक्ट स्थिर होना चाहिए या नहीं उस ऑब्जेक्ट पर निर्भर करता है जिसे आप लॉक करना चाहते हैं। यदि आप किसी वर्ग के उदाहरण को लॉक करना चाहते हैं तो आप स्थिर लॉक ऑब्जेक्ट का उपयोग नहीं कर सकते हैं। यदि आप स्थैतिक डेटा लॉक करना चाहते हैं तो आप एक इंस्टेंस लॉक ऑब्जेक्ट का उपयोग नहीं कर सकते हैं। तो ऐसा लगता है कि कोई विकल्प नहीं है।

आप उदाहरण डेटा तक पहुंच को लॉक करने के लिए एक स्थिर या आवृत्ति लॉक ऑब्जेक्ट का उपयोग करने के बारे में सोच सकते हैं, लेकिन इसके परिणामस्वरूप विभिन्न व्यवहार होते हैं। एक उदाहरण लॉक ऑब्जेक्ट के साथ आप केवल एक उदाहरण लॉक करते हैं जबकि स्थिर लॉक ऑब्जेक्ट सभी उदाहरणों को लॉक कर देगा। तो यहां प्रदर्शन ट्यूनिंग के लिए भी कोई विकल्प नहीं है।

+0

आपकी व्याख्या बहुत अधिक समझ में आता है, हालांकि इसे एक निजी स्थिर मत भूलना। बाहर से कुछ भी वैसे भी इसका उपयोग नहीं कर सकता है। – Houman

+0

यही मैंने सोचा था। लॉक ऑब्जेक्ट को गैर स्थैतिक के रूप में लॉक के दायरे को बदल देगा। –

7

उन्होंने दावा किया कारण यह है कि स्थिर संकलन के बजाय रनटाइम पर चलाया जाता है और उस वस्तु धीमी धागे अगर यह गैर स्थिर था की तुलना में लॉक करने के लिए के लिए होगा है।

यह वास्तव में कोई समझ नहीं आता है - मुझे लगता है कि साक्षात्कारकर्ता को यह नहीं पता था कि वह किस बारे में बात कर रहा था, या शायद आप उसके बिंदु को गलत समझा।

+0

मैं वही चीज़ (और टाइपिंग) सोच रहा था। –

+0

मैंने नोट्स बनाये हैं। उन्होंने कहा कि इस मामले में स्थैतिक धीमा होगा। मैं उसका बचाव नहीं कर रहा हूं मैं सच खोजने की कोशिश कर रहा हूं। :) – Houman

+0

मैं मानता हूं कि इसका कोई मतलब नहीं है – galets

0
नौकरी साक्षात्कार में

कभी कभी मैं कहता हूँ कुछ मुझे पता है वह सही नहीं है या कुछ और कि यदि उम्मीदवार को प्रभावी ढंग से अपनी बात का तर्क होगा या बस छोड़ देना और इस बात से सहमत देखने के लिए बोलना बकवास है।

ओह और यहां लॉक के उचित उपयोग पर excellent article by Jeffrey Richter है। :)

+0

क्या आप चिंतित नहीं हैं कि यह पीछे हट जाएगा? अगर मुझे नौकरी साक्षात्कारकर्ता का सामना करना पड़ा जिसने कुछ गलत राय की, तो मैं साक्षात्कार से दूर आ सकता था कि कंपनी तकनीकी दृष्टिकोण से बहुत खराब थी –

+1

नहीं, मुझे पता होना चाहिए कि क्या कोई व्यक्ति सोचता है कि वह सही है, तो वह प्रभावी ढंग से अपने बिंदु पर बहस कर सकता है। अन्यथा मेरे संगठन के अन्य डेवलपर्स उसे जिंदा खाएंगे। –

+3

प्लस, मुझे लगता है कि यह देखना बेहतर है कि आपके संभावित मालिक को राजी किया जा सकता है। एक प्रबंधक से भी बदतर कुछ भी नहीं है जो स्वीकार नहीं कर सकता कि वे गलत हैं। –

-1

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

इसके विपरीत यदि धागे वर्ग-स्तर (स्थिर) स्थिति तक पहुंच रहे हैं तो आपको उन्हें एक ही ऑब्जेक्ट से लॉक करने की आवश्यकता है। [-, सब के बाद नहीं इस तरह के एक अच्छा विचार नीचे टिप्पणी को देखने संपादित करें]

lock(typeof(MyClass)) 
{ 
    // use class-level data 
} 

: जब मैं यह करने के लिए की जरूरत है, एक पैटर्न मैं का उपयोग किया है इस तरह वर्ग के प्रकार के लॉक करने के लिए है

यह स्थिर ऑब्जेक्ट फ़ील्ड बनाने की आवश्यकता से बचाता है।

+0

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

+1

क्षमा करें, मुझे अपना वोट रद्द करना होगा। बस यह पता चला कि यह कोड वास्तव में कितना बुरा है। विवरण के लिए http://bytes.com/groups/net-c/249277-dont-lock-type-objects देखें। –

+1

यह और भी बदतर हो जाता है। लॉक (यह) एक समान रूप से खराब विकल्प है - विवरण के लिए http://msdn.microsoft.com/de-de/magazine/cc188793(en-us).aspx देखें। सबक सीखा: केवल संदर्भ उदाहरण के निजी उदाहरण या स्थैतिक वस्तुओं को लॉक करें! –

0

लॉक के लिए एक गैर स्थैतिक वस्तु का उपयोग करें जब भी आपको यह सुनिश्चित करने की आवश्यकता हो कि एक ही उदाहरण एक ही समय में अलग-अलग धागे द्वारा छेड़छाड़ नहीं किया जाता है।

आइए कहें कि आपके पास कुछ विशिष्ट श्रेणी है, जिसमें एक विशेष रीडर विधि है जो कुछ अजीब तर्क स्वीकार करता है। विचार करें कि आपको कुछ पैरालेल प्रक्रियाओं के दौरान 100 अलग-अलग सूचियों को फिर से व्यवस्थित करने की आवश्यकता है या नहीं। आप केवल देखभाल करते हैं कि अलग-अलग धागे एक ही सूची में एक ही सूची में हेरफेर नहीं करते हैं, क्योंकि यह आपके पुनरावृत्ति तर्क को प्रभावित कर सकता है। आपको स्थिर लॉक की आवश्यकता नहीं है, क्योंकि आपको परवाह नहीं है जब एक ही समय में अलग-अलग सूचियों का उपयोग किया जा रहा है।

स्थिर लॉक के साथ एक परिदृश्य का एक साधारण उदाहरण, कुछ स्थैतिक डेटा का प्रारंभिकरण है, जहां आप यह सुनिश्चित करना चाहते हैं कि भार तर्क केवल एक बार चलाया जाए। कुछ कैश या सिंगलटन की तरह।

+0

आप जो भी कहते हैं वह मान्य है। हालांकि कृपया मुझे बताएं कि यदि ऑब्जेक्ट निजी है तो क्या अंतर होता है। यदि इसका निजी कोई थ्रेड किसी भी तरह से बाहर से इसका उपयोग नहीं कर सकता है। तो इस मामले में एक निजी स्थैतिक होने का क्या मतलब है? निजी स्थिर का अर्थ मारता है। – Houman

+0

वास्तव में, निजी होने से स्थिर के साथ कोई संबंध नहीं है। वास्तव में, यह सिर्फ ताला के लिए दिया गया है, यह निजी होना चाहिए। आप चाहते हैं कि ताले वर्ग के कार्यान्वयन के अंदर हों, इसलिए बाहरी दुनिया को उजागर करने में कोई बात नहीं है। लोडिंग उदाहरणों में, आप लॉक को आंतरिक रूप से संभालना चाहते हैं जब आप स्थिर संपत्ति को कॉल करते हैं जैसे: MyClass.Current। यह वर्तमान का कार्यान्वयन है जो यह सुनिश्चित करने के लिए लॉक का उपयोग करता है कि यह दो बार उदाहरण लोड नहीं करता है। – eglasius

0

यदि आपके पास केवल एक एक वर्ग का उदाहरण है जो एकाधिक धागे के बीच साझा करता है, तो सामान्य ऑब्जेक्ट का उपयोग करना ठीक है। लेकिन यदि आपके पास एकाधिक वर्गों के बीच साझा करने वाली कक्षा की कई वस्तुएं हैं, तो आपको स्थिर ऑब्जेक्ट का उपयोग करना होगा।

दूसरी ओर, सामान्य वस्तु के साथ आप एक वर्ग के एक उदाहरण के लिए संगामिति प्रबंधन कर सकते हैं और स्थिर वस्तु के साथ आप एक वर्ग के सभी उदाहरणों के दायरे में संगामिति प्रबंधन कर सकते हैं।

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