मैंने डेडलॉक्स से बचने के लिए सिंक्रूट पैटर्न के बारे में कुछ सामान्य नियम के रूप में कुछ पढ़ा। और कुछ साल पहले एक प्रश्न पढ़ना (यह link देखें), मुझे लगता है कि मैं समझता हूं कि इस पैटर्न के कुछ उपयोग गलत हो सकते हैं। विशेष रूप से, मैं निम्नलिखित वाक्य पर ध्यान केंद्रित this topic से:सिंक्रूट पैटर्न पर कुछ स्पष्टीकरण: इस पैटर्न का उपयोग करने का सही तरीका क्या है?
आप System.Collections में संग्रह के कई पर एक SyncRoot संपत्ति पर ध्यान देंगे। पूर्व-निरीक्षण में, मुझे लगता है कि यह संपत्ति गलती थी ... बाकी आश्वासन दिया है कि हम एक ही गलती नहीं करेंगे क्योंकि हम इन संग्रहों के सामान्य संस्करण बनाते हैं।
वास्तव में, उदाहरण के लिए, List<T>
वर्ग SyncRoot
संपत्ति को लागू करता है नहीं है, या अधिक सही ढंग से यह स्पष्ट रूप से (this answer देखें) लागू किया गया है, तो आप इसका इस्तेमाल करने में ICollection
को कास्ट करना होगा। लेकिन this comment का तर्क है कि एक निजी SyncRoot
फ़ील्ड सार्वजनिक बनाना this
पर लॉकिंग के रूप में खराब अभ्यास है (this answer देखें), साथ ही this comment में भी पुष्टि की गई है।
तो, यदि मैं सही ढंग से समझता हूं, जब मैं एक गैर थ्रेड-सुरक्षित डेटा संरचना लागू करता हूं, क्योंकि इसे बहु-संदर्भित संदर्भ में उपयोग किया जा सकता है, तो मुझे SyncRoot
संपत्ति प्रदान नहीं करना चाहिए (वास्तव में, मुझे नहीं करना चाहिए)। लेकिन मुझे डेवलपर (जो इस डेटा संरचना का उपयोग करेगा) को एक निजी सिंक्रूट ऑब्जेक्ट के साथ निम्नलिखित नमूना कोड में जोड़ने के कार्य के साथ छोड़ देना चाहिए।
public class A
{
private MyNonThreadSafeDataStructure list;
private readonly object list_SyncRoot = new object;
public Method1()
{
lock(list_SyncRoot)
{
// access to "list" private field
}
}
public Method2()
{
lock(list_SyncRoot)
{
// access to "list" private field
}
}
}
सारांश में, मैं समझ गया कि तुल्यकालन/लॉकिंग के लिए सर्वोत्तम प्रथाओं के रूप में निम्नानुसार होना चाहिए:
- किसी भी निजी SyncRoot वस्तुओं एक सार्वजनिक संपत्ति के माध्यम से संपर्क में नहीं किया जाना चाहिए, दूसरे शब्दों में, एक कस्टम डेटा संरचना को सार्वजनिक
SyncRoot
संपत्ति प्रदान नहीं करना चाहिए (this comment भी देखें)। - सामान्य रूप से, लॉकिंग के लिए निजी वस्तुओं का उपयोग करना अनिवार्य नहीं है (this answer देखें)।
- यदि किसी वर्ग में संचालन के कई सेट होते हैं जिन्हें सिंक्रनाइज़ करने की आवश्यकता होती है, लेकिन एक दूसरे के साथ नहीं, तो इसमें कई निजी सिंक्रूट ऑब्जेक्ट्स होनी चाहिए (this comment देखें)।
क्या इस पैटर्न के उचित उपयोग से ऊपर लिखा गया है?
मेरी राय यह है कि यदि आप आंतरिक रूप से कक्षा थ्रेड-सुरक्षित बनाना चाहते हैं, तो आप आंतरिक रूप से (निजी रूप से) लॉकिंग करते हैं और दस्तावेज़ करते हैं कि कक्षा आम तौर पर थ्रेड-सुरक्षित है। अन्यथा, _no लॉकिंग_ करें, दस्तावेज़ कि कक्षा थ्रेड-सुरक्षित नहीं है, और अपने वर्ग के उपभोक्ताओं को अपने विशिष्ट उपयोग के लिए अपनी लॉकिंग लागू करने दें। –