2010-02-23 13 views

उत्तर

11

अंतर यह है कि कोई भी आपके उदाहरण को लॉक कर सकता है, लेकिन केवल आप ही एक निजी वस्तु को लॉक कर सकते हैं।

यह डेडलॉक्स को रोकने में मदद करता है।

उदाहरण के लिए:

कहते हैं कि माइक्रोसॉफ्ट Control कक्षा में lock(this) इस्तेमाल किया करते हैं।

फिर, अगर कोई अन्य Control उदाहरण पर लॉक करता है, तो उसका लॉक कोड को Control में चलने से रोक देगा, जो वह नहीं चाहता है।

अगर आप lock on types that are shared across AppDomains

+0

कमजोर पहचान ताले के बारे में अच्छा बिंदु। –

17

lock(this) "वर्तमान" वस्तु पर लॉक हो जाएगा विशेष रूप से खराब है।

"यह" पर लॉक करना आमतौर पर एक बुरा विचार है क्योंकि यह अन्य कोड को लॉक का खुलासा करता है; मैं एक केवल पढ़ने के लिए क्षेत्र के लिए पसंद करते हैं, इस तरह:

public class Foo 
{ 
    private readonly object padlock = new object(); 

    public void SomeMethod() 
    { 
     lock(padlock) 
     { 
      ... 
     } 
    } 
} 

इस तरह SomeMethod (और Foo जो padlock पर ताले में कुछ और) के लिए सभी कॉल Foo का एक ही उदाहरण के लिए एक ही मॉनीटर पर लॉक हो जाएगा, लेकिन कुछ भी अन्य उस मॉनीटर पर लॉक करके हस्तक्षेप कर सकते हैं।

हकीकत में, जब तक कि आप "धूर्त" कोड के साथ काम कर रहे हैं, यह संभावना नहीं है कि अन्य कोड वास्तव में Foo का एक उदाहरण के संदर्भ पर लॉक हो जाएगा, लेकिन यह कैप्सूलीकरण की बात है।

+1

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

+0

'पैडलॉक' में एक प्रकार की घोषणा गायब प्रतीत होती है। – Dan

+0

@ डैन: फिक्स्ड, धन्यवाद। –

1

वहाँ गुंजाइश में एक फर्क है और वहाँ व्यवहार (संयोग में एक फर्क, का उपयोग करते हुए "इस" एमएस

 

// in this case, your lock object is public, so classes outside of this can lock on the same thing 
lock(this) {} 

// in this case, your lock is private, and only you can issue a lock statement against it 
private object lockobj = new object() 
.. 
lock(this.lockobj) {} 

// this one is WRONG -- you willget a new object instance every time, so your lock will not provide mutual exclusion 
void SomeMethod() 
{ 
    // using a local variable for a lock -- wrong 
    object obj = new object(); 
    lock(obj) {} 
} 
 
3

पैटर्न मैं आमतौर पर का पालन करें द्वारा अनुशंसित नहीं है हो सकता है, यह है एक वर्ग घोषित के लिए static ....

 
public static class SomeClass{ 
    private static object objLock = new object(); 
    .... 
    public static object SomeProperty{ 
     get{ 
      lock(objLock){ 
      // Do whatever needs to be done 
      } 
     } 
     set{ 
      lock(objLock){ 
      } 
     } 
    } 
} 
इसी तरह एक सामान्य वर्ग मैं इस पैटर्न का पालन करेंगे के लिए

:

 
public class SomeClass{ 
    private readonly object objLock = new object(); 
    .... 
    public object SomeProperty{ 
     get{ 
      lock(objLock){ 
      // Do whatever needs to be done 
      } 
     } 
     set{ 
      lock(objLock){ 
      } 
     } 
    } 
} 

कि रास्ते में, कोई भी मेरा उदाहरण पर ताला और घटनेवाला से गतिरोध पाएगा कर सकते हैं ...

संपादित करें: मैं इस लेख में संशोधन किया है यह कोड के संबंध में स्पष्ट करने के जहां के आधार static लॉक का उपयोग किया जाएगा और सामान्य कक्षा के लिए ...धन्यवाद स्टीवन और Dalle उनके नज़रिए बहिष्कार के लिए ...

+1

क्या आप वाकई 'स्थिर' लॉक का इरादा रखते हैं? – dalle

+0

@dalle: हाँ, मैं इसे एक स्थिर वर्ग में उपयोग करूँगा, मैं सामान्य कक्षा के भीतर 'निजी रीडोनली ऑब्जेक्ट objLock = new object()' निम्नलिखित करता हूं। क्या इससे आपके सवाल का जवाब मिलता है? :) – t0mm13b

+0

यह आपके उदाहरण से स्पष्ट नहीं था कि आप एक स्थिर वर्ग में थे। अब जब आपने इसे निर्दिष्ट किया है, तो यह लॉकर के स्थिर होने के लिए भी समझ में आता है। आपके नामकरण सम्मेलन आपके इरादे को समझना कठिन बनाते हैं, क्योंकि वे .NET मानकों का उल्लंघन करते हैं। –

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