2013-01-07 12 views
8

बाद मैंफ़ील्ड या स्थानीय चर पर लॉकिंग?

मैं कभी कभी लोगों को एक स्थानीय चर पर ताला लगा देख an answer मार्क से साथ this सवाल .... पढ़ें।

क्या यह कोड टूटा हुआ है?

public void Do() 
{ 
object o = new Object(); 
lock (o) 
    { 
     ... 
    } 
} 

मेरा मानना ​​है कि object o = new Object(); बाहर होना चाहिए एक Field के रूप में विधि।

चूंकि प्रत्येक थ्रेड को o का नया उदाहरण मिल रहा है, तो कई ताले होंगे।

मुझे यहां क्या याद आ रही है? क्या इस विशिष्ट मामले में फ़ील्ड को लॉक नहीं करना चाहिए?

उत्तर

8

मेरा मानना ​​है कि वस्तु ओ = नई वस्तु(); एक फ़ील्ड के रूप में विधि के बाहर होना चाहिए।

चूंकि प्रत्येक थ्रेड को ओ का नया उदाहरण मिल रहा है, तो कई ताले होंगे।

क्या मुझे कुछ भी याद आ रही है? क्योंकि मुझे पता है कि इसे खेतों में लॉक करना चाहिए (इस विशिष्ट मामले में)।

आपकी समझ सही है। कोड टूटा हुआ है। इस कार्यान्वयन में हालांकि लॉक सक्रिय होगा, यह सिंक्रनाइज़ेशन प्रदान नहीं करेगा क्योंकि यह विभिन्न वस्तुओं पर होगा।

से MSDN-lock c#

सामान्य तौर पर, एक सार्वजनिक प्रकार पर ताला लगा बचने के लिए, या अपने कोड के नियंत्रण से बाहर उदाहरणों।आम निर्माणों ताला (यह), ताला (typeof (MyType)), और ताला ("myLock") इस निर्देश का उल्लंघन:

  • ताला (यह) एक समस्या है, तो उदाहरण के सार्वजनिक रूप से पहुँचा जा सकता है है।
  • लॉक (टाइपोफ (माईटाइप)) एक समस्या है यदि MyType सार्वजनिक रूप से सुलभ है।
  • लॉक ("myLock") एक समस्या है क्योंकि प्रक्रिया में किसी अन्य कोड को एक ही स्ट्रिंग का उपयोग करके, उसी लॉक को साझा किया जाएगा।

सर्वोत्तम अभ्यास किसी अन्य ऑब्जेक्ट को लॉक करने के लिए, या एक निजी स्थिर ऑब्जेक्ट वैरिएबल को सभी उदाहरणों के लिए सामान्य डेटा की सुरक्षा के लिए परिभाषित करना है।

2

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

2

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

स्थानीय चर होने के कारण हर बार एक नया उदाहरण आवंटित किया जाएगा, इसलिए प्रत्येक थ्रेड के लिए यह ठीक रहेगा।

इसमें कोई अर्थ नहीं दिख रहा है।

5

हां। यह टूटा हुअा है।

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

private static object syncRoot = new object(); 

lock (syncRoot) { } 
+0

यह स्थिर होना आवश्यक नहीं है। (जब तक कि एक अलग उदाहरण को लक्षित न किया जाए) –

+0

इसे स्थैतिक रूप से पढ़ना इसे नुकसान नहीं पहुंचाता है, केवल इसे सुरक्षित करता है (भले ही इसकी आवश्यकता नहीं है) – Tilak

+2

सहमत हैं। यह स्थिर होना जरूरी नहीं है। आप जो सुरक्षा कर रहे हैं उस पर निर्भर करता है। –

1

स्थानीय चर पर लॉकिंग, लॉक जीता गया काम। वैश्विक चर पर लॉकिंग कई थ्रेड सिंक्रनाइज़ करने के लिए प्रभावी हो सकता है।

using System; 
     using System.Collections.Generic; 
     using System.Linq; 
     using System.Text; 
     using System.Threading.Tasks; 
     using System.Threading; 

     namespace testLock 
     { 
      class Program 
      { 
       public static void Main() 
       { 
        // Start a thread that calls a parameterized static method. 
        for(int i = 0; i< 10;i++) 
        { 
         Thread newThread = new Thread(DoWork); 
         newThread.Start(i); 
        } 

        Console.ReadLine(); 
       } 

       static object gObject= new object(); 
       public static void DoWork(object data) 
       { 
        int len = (int)data % 3; 
        object tmp = new object(); 
        Console.WriteLine("to lock...... Data='{0}' sleepTime:{1}", data, len); 
        lock (tmp)//tmp won't work, change tmp to gObject to see different output, which is good locking case) 
        { 
         Console.WriteLine("in lock...... Data='{0}' sleepTime:{1}", data, len); 

         Thread.Sleep( len* 1000); 
         Console.WriteLine("Static thread procedure. Data='{0}' sleepTime:{1}", data, len); 
        } 
       } 

      } 
     } 

    **Lock temp variable,will output:** 
    to lock...... Data='1' sleepTime:1 
    in lock...... Data='1' sleepTime:1 
    to lock...... Data='2' sleepTime:2 
    in lock...... Data='2' sleepTime:2 
    to lock...... Data='0' sleepTime:0 
    in lock...... Data='0' sleepTime:0 
    Static thread procedure. Data='0' sleepTime:0 
    to lock...... Data='3' sleepTime:0 
    in lock...... Data='3' sleepTime:0 
    Static thread procedure. Data='3' sleepTime:0 
    to lock...... Data='4' sleepTime:1 
    in lock...... Data='4' sleepTime:1 
    to lock...... Data='5' sleepTime:2 
    in lock...... Data='5' sleepTime:2 
    to lock...... Data='6' sleepTime:0 
    in lock...... Data='6' sleepTime:0 
    Static thread procedure. Data='6' sleepTime:0 
    to lock...... Data='7' sleepTime:1 
    in lock...... Data='7' sleepTime:1 
    to lock...... Data='8' sleepTime:2 
    in lock...... Data='8' sleepTime:2 
    to lock...... Data='9' sleepTime:0 
    in lock...... Data='9' sleepTime:0 
    Static thread procedure. Data='9' sleepTime:0 
    Static thread procedure. Data='1' sleepTime:1 
    Static thread procedure. Data='4' sleepTime:1 
    Static thread procedure. Data='7' sleepTime:1 
    Static thread procedure. Data='2' sleepTime:2 
    Static thread procedure. Data='5' sleepTime:2 
    Static thread procedure. Data='8' sleepTime:2 

    **Then lock gObject, will print:** 
    to lock...... Data='0' sleepTime:0 
    in lock...... Data='0' sleepTime:0 
    to lock...... Data='1' sleepTime:1 
    to lock...... Data='2' sleepTime:2 
    Static thread procedure. Data='0' sleepTime:0 
    in lock...... Data='1' sleepTime:1 
    to lock...... Data='3' sleepTime:0 
    to lock...... Data='4' sleepTime:1 
    to lock...... Data='5' sleepTime:2 
    to lock...... Data='6' sleepTime:0 
    to lock...... Data='7' sleepTime:1 
    to lock...... Data='8' sleepTime:2 
    to lock...... Data='9' sleepTime:0 
    Static thread procedure. Data='1' sleepTime:1 
    in lock...... Data='5' sleepTime:2 
    Static thread procedure. Data='5' sleepTime:2 
    in lock...... Data='9' sleepTime:0 
    Static thread procedure. Data='9' sleepTime:0 
    in lock...... Data='2' sleepTime:2 
    Static thread procedure. Data='2' sleepTime:2 
    in lock...... Data='8' sleepTime:2 
    Static thread procedure. Data='8' sleepTime:2 
    in lock...... Data='7' sleepTime:1 
    Static thread procedure. Data='7' sleepTime:1 
    in lock...... Data='4' sleepTime:1 
    Static thread procedure. Data='4' sleepTime:1 
    in lock...... Data='3' sleepTime:0 
    Static thread procedure. Data='3' sleepTime:0 
    in lock...... Data='6' sleepTime:0 
    Static thread procedure. Data='6' sleepTime:0 
+0

सी # में कोई वैश्विक चर नहीं हैं। – Enigmativity

+1

आप सही हैं, इस उदाहरण में वैश्विक चर मेरा मतलब है कि कक्षा कार्यक्रम में स्थिर चर है। – terwxqian

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