2012-05-14 10 views
12

मैंने जावा में अव्यवस्था और धागे सीखना शुरू कर दिया है। मैं सिंक्रनाइज़ की मूल बातें जानता हूं (यानी यह क्या करता है)। संकल्पनात्मक रूप से मैं समझता हूं कि यह जावा में एकाधिक धागे के साथ एक साझा संसाधन की पारस्परिक अनन्य पहुंच प्रदान करता है। लेकिन जब नीचे एक उदाहरण का सामना करना पड़ा तो मैं उलझन में हूं यह सिंक्रनाइज़ करने का एक अच्छा विचार है। मुझे पता है कि कोड के महत्वपूर्ण वर्गों को समेकित किया जाना चाहिए और इस कीवर्ड को अधिक उपयोग नहीं किया जाना चाहिए या यह प्रदर्शन को प्रभावित करता है।सिंक्रनाइज़ेशन, कब उपयोग करना है या नहीं?

public static synchronized List<AClass> sortA(AClass[] aArray) 
{ 
    List<AClass> aObj = getList(aArray); 

    Collections.sort(aObj, new AComparator()); 

    return aObj; 
} 

public static synchronized List<AClass> getList(AClass[] anArray) 
{ 
    //It converts an array to a list and returns 
} 
+2

क्योंकि अपने तरीके राज्यविहीन लगते हैं। – Luca

उत्तर

9

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

इसके बजाय यदि आपने कुछ धागे सभी sortA बुला और एक ही सरणी के लिए एक संदर्भ गुजर, बंद आग आप क्योंकि वे eachother के साथ हस्तक्षेप करेगा, synchronized बिना मुसीबत में होगी।

सावधान रहें, कि यह उदाहरण से प्रतीत होता है कि getList विधि एक सरणी से एक नया List देता है, ऐसी है कि भले ही धागे में एक ही सरणी गुजरती हैं, आप विभिन्न List वस्तुओं मिलता है। यह भ्रामक है। उदाहरण के लिए, Arrays.asList का उपयोग करके दिए गए सरणी द्वारा समर्थित List बनाता है, लेकिन जावाडोक स्पष्ट रूप से बताता है कि Changes to the returned list "write through" to the array. इसलिए इस बारे में सावधान रहें।

2

आपकी स्थिर विधियां किसी भी साझा स्थिति पर निर्भर नहीं हैं, इसलिए सिंक्रनाइज़ नहीं होने की आवश्यकता है।

2

कोई नियम जब नहीं जब सिंक्रनाइज़ का उपयोग करें और, जब आप सुनिश्चित करें कि आपके कोड समवर्ती धागे द्वारा पहुँचा जा नहीं होगा तो आप सिंक्रनाइज़ का उपयोग कर से बचने कर सकते हैं की तरह परिभाषित किया गया है।

2

तुल्यकालन आप सही तरीके से लगा के रूप में अपने आवेदन के प्रवाह पर प्रभाव पड़ता है, और यह भी धागा भूख से मर करने के लिए नेतृत्व कर सकते हैं।

सभी मूल रूप से प्राप्त गैर अवरुद्ध होना चाहिए के रूप में संगामिति पैकेज के अंतर्गत संग्रह लागू किया है।

आपके उदाहरण में सभी कॉलिंग थ्रेड अपनी सरणी की प्रतिलिपि पास करेंगे, getList को सिंक्रनाइज़ करने की आवश्यकता नहीं है, इसलिए sortA विधि है क्योंकि अन्य सभी चर स्थानीय हैं।

स्थानीय चर ढेर पर रहते हैं और हर धागा अपने स्वयं के ढेर तो अन्य थ्रेड इसके साथ हस्तक्षेप नहीं कर सकता है।

जब आप ऑब्जेक्ट की स्थिति बदलते हैं तो आपको सिंक्रनाइज़ेशन की आवश्यकता होती है कि अन्य थ्रेड एक स्थिर स्थिति में देखना चाहिए, यदि आपकी कॉल उस ऑब्जेक्ट की स्थिति को नहीं बदलती है जिसे आपको सिंक्रनाइज़ेशन की आवश्यकता नहीं है।

3

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

ऊपर कोड स्निपेट में, वहाँ कोई डेटा साझा किए जा रहे है। उपलब्ध कराए गए इनपुट पर विधियां काम करती हैं और आउटपुट लौटाती हैं। यदि एकाधिक धागे आपकी विधि में से किसी एक को आमंत्रित करते हैं, तो प्रत्येक आमंत्रण का अपना इनपुट और आउटपुट होगा। इसलिए, कहीं भी स्थिरता का कोई मौका नहीं है। इसलिए, उपरोक्त स्निपेट में आपके तरीकों को समेकित करने की आवश्यकता नहीं है।

सिंक्रनाइज़ेशन, यदि अनावश्यक रूप से उपयोग किया जाता है, तो सुनिश्चित किए गए ओवरहेड के कारण प्रदर्शन को कम कर देगा और इसलिए सावधानीपूर्वक उपयोग किए जाने पर सावधानीपूर्वक उपयोग किया जाना चाहिए।

+0

आप कैसे जानते हैं कि कोई डेटा साझा नहीं किया जा रहा है? धागे एक ही सरणी को 'sortA' विधि में पास कर सकते हैं। – Tudor

+1

काफी संभावना है! खैर, उस मामले में आपको निश्चित रूप से synchornize की आवश्यकता होगी। मुद्दा यह है कि कोड के उपयोगकर्ताओं को पता होना चाहिए कि आपका कोड थ्रेड सुरक्षित है या नहीं। एक डेवलपर के रूप में, आप जानते हैं कि आपका कोड थ्रेड सुरक्षित होना चाहिए या नहीं। यदि नहीं, तो आपको उपयोगकर्ताओं के लिए इसे दस्तावेज़ करने की आवश्यकता है ताकि वे दिलचस्प परिदृश्यों में स्पष्ट रूप से सिंक्रनाइज़ हो सकें। आपको अपने कोड में सबकुछ सिंक्रनाइज़ करने की आवश्यकता नहीं है। – Drona

+1

उपरोक्त स्निपेट में एक स्थिर विधि सिंक्रनाइज़ करने के लिए जो कार्यक्षमता प्रदान करता है वह सही नहीं है। उपयोगकर्ताओं को जहां भी आवश्यक हो वहां बाहरी रूप से वर्णित परिदृश्य के खिलाफ सुरक्षा करनी चाहिए। – Drona

2

मैं एकल थ्रेडेड कोड पर synchronized का उपयोग नहीं करता। यानी जहां कोई मौका नहीं है कि ऑब्जेक्ट को कई धागे से एक्सेस किया जाएगा।

यह स्पष्ट नहीं तुल्यकालन की जरूरत दिखाई दे सकते हैं, लेकिन ~ JDK में इस्तेमाल StringBuffer के 99% केवल एक धागा द्वारा इस्तेमाल किया जा सकता एक StringBuilder (जो सिंक्रनाइज़ नहीं कर रहा है) के साथ बदला जा सकता है