2012-07-17 14 views
19

मैं निम्नलिखित लॉक बयान है:क्या लॉक वैरिएबल को अस्थिर घोषित किया जाना चाहिए?

private readonly object ownerLock_ = new object(); 

lock (ownerLock_) 
{ 
} 

मैं अपने ताला चर के लिए volatile कीवर्ड उपयोग करना चाहिए?

private readonly volatile object ownerLock_ = new object(); 

MSDN पर मैंने देखा कि यह आमतौर पर एक क्षेत्र है कि ताला लगा के बिना पहुँचा जा सकता है के लिए इस्तेमाल किया है, इसलिए यदि मैं लॉक का उपयोग मैं अस्थिर उपयोग करने की आवश्यकता नहीं है?

MSDN से

:

अस्थिर संशोधक आम तौर पर एक क्षेत्र है कि पहुँच क्रमानुसार करने ताला बयान का उपयोग किए बिना से अधिक थ्रेड द्वारा पहुँचा है के लिए प्रयोग किया जाता है।

+0

हमें प्रश्न का उत्तर देने के लिए उससे कहीं अधिक संदर्भ की आवश्यकता है। लॉक का उपयोग करने वाली वस्तुओं के संबंध में यह लॉक कहां मौजूद है? –

+3

यह निश्चित रूप से थ्रेड सुरक्षित है क्योंकि यह वर्तमान में मौजूद है। जब आप लॉक {} ब्लॉक में कोड जोड़ते हैं तो कोई गारंटी संभव नहीं होगी। –

+0

आपको 'readonly' ऑब्जेक्ट को लॉक करने की आवश्यकता नहीं है ... जिसमें यह' readonly' है ... – NominSim

उत्तर

18

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

volatileबहुत शायद ही कभी एप्लिकेशन कोड में उपयोग किया जाना चाहिए। यदि आप एक चर के लिए लॉक-फ्री पहुंच चाहते हैं, तो Interlocked लगभग हमेशा के लिए आसान है। यदि आप उससे परे लॉक-फ्री एक्सेस चाहते हैं, तो मैं लगभग हमेशा लॉक करना शुरू कर दूंगा। (या शुरू करने के लिए अपरिवर्तनीय डेटा संरचनाओं का उपयोग करने का प्रयास करें।)

मुझे केवल volatile को कोड के भीतर देखने की उम्मीद है जो थ्रेडिंग के लिए उच्च स्तरीय abstractions बनाने की कोशिश कर रहा है - उदाहरण के लिए, टीपीएल कोडबेस के भीतर। यह वास्तव में उन विशेषज्ञों के लिए एक उपकरण है जो वास्तव में .NET मेमोरी मॉडल को अच्छी तरह से समझते हैं ... जिनमें से बहुत कम हैं, आईएमओ।

+0

आपके त्वरित उत्तर के लिए धन्यवाद, आइए कहें कि मैं केवल लॉक का उपयोग कर रहा हूं, यह दुर्लभ लगता है लेकिन लॉक स्टेटमेंट में आने वाले 2 थ्रेड दोनों एक ही समय में मालिक लॉक_ राज्य की जांच करेंगे और इसे एक-दूसरे को लॉक करने का प्रयास करेंगे? मैं इस सवाल से पूछ रहा हूं क्योंकि मुझे अपने कोड में लॉकिंग में समस्या थी और मुझे लगता है कि यह इस मुद्दे से संबंधित है। –

+0

@ डोरकोहेन: उनमें से केवल एक ही समय में लॉक प्राप्त करेगा। इसके बाद यह 'लॉक' कथन के शरीर को निष्पादित करेगा, और जब यह लॉक जारी करेगा, तो दूसरा थ्रेड लॉक प्राप्त करने और कोड निष्पादित करने में सक्षम होगा। –

+0

@DorCohen, ऐसा लगता है कि आपकी समस्या उस लॉकिंग में नहीं है जो आप लॉक कर रहे हैं, लेकिन आप लॉक बॉडी के भीतर क्या करने का प्रयास कर रहे हैं। –

2

यदि कुछ readonly है तो यह थ्रेड-सुरक्षित, अवधि है। (ठीक है, लगभग एक विशेषज्ञ आपके lock कथन पर NullReferenceException प्राप्त करने के तरीके को समझने में सक्षम हो सकता है, लेकिन यह आसान नहीं होगा।) readonly के साथ आपको volatile, Interlocked, या लॉकिंग की आवश्यकता नहीं है। यह बहु-थ्रेडिंग के लिए आदर्श कीवर्ड है, और आपको इसका उपयोग करना चाहिए जहां आप कभी भी कर सकते हैं। यह लॉक ऑब्जेक्ट के लिए बहुत अच्छा काम करता है जहां इसका बड़ा नुकसान (आप मूल्य नहीं बदल सकते हैं) इससे कोई फर्क नहीं पड़ता।

इसके अलावा, संदर्भ अपरिवर्तनीय है, ऑब्जेक्ट संदर्भित नहीं हो सकता है। "नया ऑब्जेक्ट()" यहां है, लेकिन अगर यह List था या कुछ और परिवर्तनीय - और थ्रेड-सुरक्षित नहीं - आप संदर्भ को लॉक करना चाहते हैं (और इसके सभी अन्य संदर्भ, यदि कोई हैं) रखने के लिए एक बार में दो धागे में बदलने से वस्तु।

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