2009-10-23 9 views
10

मेरे मल्टीथ्रेडिंग एप्लिकेशन में मैं कुछ चर का उपयोग कर रहा हूं जिसे एक ही समय में कई उदाहरणों में बदला जा सकता है। यह अजीब है लेकिन उसने बिना किसी समस्या के ठीक काम किया है .. लेकिन निश्चित रूप से मुझे इसे थ्रेड-सुरक्षित बनाना होगा। मैं सिर्फ ताले से शुरुआत कर रहा हूं इसलिए मैं आपकी सलाह को अपमानित करूंगा:गुणों में लॉक, अच्छा दृष्टिकोण?

जब क्लाइंट कनेक्ट होता है, क्लास क्लाइंट बनाया जाता है जहां प्रत्येक क्लाइंट का अपना "ए" चर होता है। अब उस के साथ जब तक

Client selectedClient SelectOtherClientClassByID(sentID); 

selectedClient.A=5; 

कोई समस्या नहीं है, तब भी जब 5 कक्षाएं एक ही समय (ThreadPool) कर रहे थे, लेकिन मैं एक गुणों के ताले जोड़ने के बारे में क्या सोच रहा था:

कभी कभी, ग्राहक ऐसे ही प्रणाली को बुलाती है ?

तरह:

A { 
    get { return mA; } 
    set { 
     // use lock here for settting A to some value 
    }  
} 

यह ठीक होगा?

उत्तर

16

आपको दोनों को लॉक और सेट में ताले का उपयोग करने की आवश्यकता है। यह ताला एक ही वस्तु होना चाहिए। उदाहरण के लिए:

private object mylock = new object(); 

public int A { 

    get { 
    int result; 
    lock(mylock) { 
    result = mA; 
    } 
    return result; 
    } 

    set { 
    lock(mylock) { 
     mA = value; 
    } 
    } 
} 
+1

धन्यवाद ... पढ़ने के लिए बीटीडब्ल्यू इसकी वजह यह अन्य वर्ग द्वारा पढ़ने के दौरान बदल सकती है? – Petr

+1

इस पर लॉक करना एक अच्छा विचार नहीं है, क्योंकि यह प्रकार के बाहर से सुलभ है। –

+0

यह सेटिंग के दौरान बदल सकता है। लॉक बाधा के रूप में कार्य करता है, जब तक कि लॉक मालिक लॉक जारी नहीं करता तब तक किसी भी अन्य क्रिया को रोकता है। –

2

यह बहुत दुर्लभ है जब आपको केवल एक ही संपत्ति सेट करना है। अधिकतर selectedClient.A = 5 एक बहुत बड़े लॉजिकल ऑपरेशन का हिस्सा होगा, जिसमें कई असाइनमेंट/मूल्यांकन/आदि शामिल हैं। उस पूरे ऑपरेशन के दौरान आप लगातार राज्य में रहने के लिए selectedClient पसंद करेंगे और डेडलॉक्स/रेस स्थितियों को पेश नहीं करेंगे। इसलिए, यह काफी बेहतर हो अपने Client कक्षा में SyncRoot संपत्ति का खुलासा और पर ताला कि बुला कोड से करने के लिए होगा:

Client selectedClient = GetClient(...); 

lock(selectedClient.SyncRoot) 
{ 
    selectedClient.A = 5; 
    selectedClient.B = selectedClient.A * 54; 
} 
+0

मेरे पास एक सूची और उन int से साझा करने वाले कोई अन्य चर नहीं हैं। मुख्य रूप से, मुझे अभी तक सिंक रूट के बारे में कुछ भी नहीं पता :) – Petr

+0

सिंक्रूट की अनुशंसा नहीं की जाती है: http://blogs.msdn.com/brada/archive/2003/09/28/50391.aspx –

+0

@_NT देखें: ब्लॉग पोस्ट से उद्धरण: "आश्वस्त रहें कि हम वही गलती नहीं करेंगे क्योंकि हम इन संग्रहों के सामान्य संस्करण बनाते हैं।"और यहां हम 6 साल बाद, सूची के साथ हैं। एमएसडीएन में किसी भी निराशाजनक नोट्स के बिना .SyncRoot: http://msdn.microsoft.com/en-us/library/bb356596.aspx –

6

accessors के अंदर गुणों में पहुंच लॉकिंग फर्जी परिणाम हो सकता है। उदाहरण के लिए, निम्न कोड को देखो:

class C { 
    private object mylock = new object(); 

    public int A { 

     get { 
     int result; 
     lock(mylock) { 
     result = mA; 
     } 
     return result; 
     } 

     set { 
     lock(mylock) { 
      mA = value; 
     } 
     } 
    } 
} 
C obj = new C; 
C.A++; 

(हाँ, मैं यह पहली बार जवाब से कॉपी किया गया) एक रेस स्थिति यहाँ नहीं है! ऑपरेशन "सीए ++" को वास्तव में ए को दो अलग-अलग एक्सेस की आवश्यकता होती है, एक मूल्य प्राप्त करने के लिए और दूसरा अद्यतन मूल्य निर्धारित करने के लिए। कुछ भी सुनिश्चित नहीं करता है कि इन दो अभिगमों को उनके बीच संदर्भ स्विच के बिना एक साथ किया जाएगा। दौड़ की स्थिति के लिए शास्त्रीय परिदृश्य!

तो, सावधान रहें! ताले को एक्सेसर्स के अंदर रखना अच्छा नहीं है, ताले स्पष्ट रूप से प्राप्त किए जाने चाहिए, जैसा पिछला उत्तर सुझाता है (हालांकि इसे सिंक रूट्स के साथ नहीं होना चाहिए, कोई ऑब्जेक्ट करेगा)

+0

क्या आप का मतलब कोड में सभी कॉलों को मैन्युअल रूप से लॉक ऑब्जेक्ट जोड़ना है? मुझे लगता है कि अब तक मेरे कोड में कम से कम 20 रीडिंग और 15 लेख हैं। – Petr

+0

ऐसा करने के लिए आप अपने महत्वपूर्ण लॉक को पूरे महत्वपूर्ण क्षेत्र को कवर करने के लिए विस्तार करते हैं। टी + ए ++। –

+0

एनटी: मैं आपको शायद अच्छी तरह से समझ नहीं पा रहा हूं। मेरे पास अलग-अलग उदाहरणों पर उस चर के साथ विभिन्न परिचालनों के साथ लगभग 15 तरीके हैं। मुझे यकीन नहीं है कि आप का विस्तार कैसे करना है कश्मीर। तो गुणों को लॉक अच्छा नहीं है अगर मैं – Petr

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