2013-02-18 23 views
17

उदाहरण के लिए, क्या यह बेहतर है? बेहतरएक कोशिश ब्लॉक के अंदर एक सिंक्रनाइज़ ब्लॉक या एक सिंक्रनाइज़ ब्लॉक के अंदर एक कोशिश ब्लॉक बेहतर है?

try { 
    synchronized (bean) { 
     // Write something    
    } 
} catch (InterruptedException e) { 
    // Write something 
} 

या यह है इस:

synchronized (bean) { 
    try {   
     // Write something    
    } 
    catch (InterruptedException e) { 
     // Write something 
    } 
} 

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

उत्तर

11

एक बेहतर ब्लॉक या एक सिंक्रनाइज़ ब्लॉक के अंदर एक कोशिश ब्लॉक के अंदर एक सिंक्रनाइज़ ब्लॉक होना बेहतर है?

आपके द्वारा स्पष्ट रूप catch जरूरत synchronized ब्लॉक में हो सकता है, मैं संभव के रूप में छोटे कोड का synchronized खंड बनाने के लिए और यह ट्राई/कैच के अंदर होगा। तो पहला पैटर्न बेहतर होगा। फिर यदि आपको catch सेक्शन में ऑपरेशन करने की आवश्यकता है (जैसे अपवाद लॉग करें या थ्रेड को फिर से बाधित करें, तो नीचे देखें), ये अन्य धागे को अवरुद्ध नहीं करेंगे।

जिसके अनुसार, अगर synchronized ब्लॉक लाइनों की एक संख्या (आमतौर पर नहीं निश्चित रूप से एक अच्छा विचार है) शामिल हैं तो मैं आज़माएं/कैच ब्लॉक विधि है कि अपवाद (prolly wait या notify) फेंकता के पास ले जाने पर विचार करेंगे। बड़ी संख्या में लाइनों के साथ, आप बड़ी कोशिश/पकड़ ब्लॉक के साथ अपवादों को अनुचित तरीके से संभालने का जोखिम चलाते हैं। यहां संदर्भ के फ्रेम पर थोड़ा सा निर्भर करता है।

एक तरफ के रूप में, सुनिश्चित करें कि आप कम से कम बाधित अपवाद लॉग इन करें। उन्हें केवल अनदेखा न करें। आप शायद थ्रेड को फिर से बाधित करना चाहते हैं:

try { 
    ... 
} catch (InterruptedException e) { 
    // always a good pattern 
    Thread.currentThread().interrupt(); 
    // handle the interrupt here by logging or returning or ... 
} 
+0

'फिर यदि आपको पकड़ अनुभाग में संचालन करने की आवश्यकता है ... तो ये अन्य धागे को अवरुद्ध नहीं करेंगे।' हम अपवाद के कारण लॉक क्यों छोड़ देंगे? – Cratylus

+0

@Gray की तरह, आपको पकड़ने की क्रिया को सिंक्रनाइज़ करने के लिए, या जितना संभव हो सके छोटे सिंक्रनाइज़ किए गए ब्लॉक को सिंक्रनाइज़ करने के लिए आपको इच्छित प्रभाव के अनुसार चयन करना होगा। लेकिन, मुझे लगता है कि आपको उस कोड के आस-पास के प्रयास/पकड़ ब्लॉक को रखने के लिए विचार करना चाहिए, जिसे आप वास्तव में संरक्षित करना चाहते हैं, बड़े ब्लॉक से परहेज करते हुए कहा, हम इन दो अच्छी प्रोग्रामिंग प्राइसियों को सारांशित कर सकते हैं: 1. छोटे सिंक्रनाइज़ किए गए ब्लॉक रखें 2. रखें उस कोड के आस-पास के ब्लॉक को आज़माएं/पकड़ें जिसे आप वास्तव में संरक्षित करना चाहते हैं। –

+0

"अपवाद के कारण हम लॉक क्यों छोड़ देंगे"। चूंकि लॉग कॉल सिंक्रोनस हो सकती है और महंगे हैं? यह उस कोड पर निर्भर करता है जो 'कैच' ब्लॉक @ क्रेटिलस में है। – Gray

0

क्या इससे कोई फर्क पड़ता है कि आपका कैच ब्लॉक सिंक्रनाइज़ किया गया है? चूंकि आपको वहां कुछ "लिखना" है, मुझे लगता है कि आप कुछ लॉगिंग करने जा रहे हैं, जिसे एक अच्छा लॉगिंग फ्रेमवर्क के साथ सिंक्रनाइज़ करने की आवश्यकता नहीं है जिसका मतलब होगा कि उत्तर शायद नहीं है।

सामान्य रूप से आपके लक्ष्य को जितना संभव हो सके छोटे सिंक्रनाइज़ेशन के रूप में उपयोग करना चाहिए। आपके सिंक्रनाइज़ेशन जितना छोटा होगा उतनी कम संभावना है कि आप समस्याओं में भाग लेंगे।

3

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

0

इस मामले में, InterruptedException केवल synchronized ब्लॉक जहां या तो कह सकते हैं wait या sleep या notify अंदर हो सकता है।

सामान्यतः सबसे अच्छा अभ्यास try/catch ब्लॉक को उस कोड के करीब रखना है जो अपवाद फेंक सकता है ताकि कोड को ठीक करने के लिए कोड को पहचानना आसान हो।

0

यह synchronized{try{}} या try{synchronized{}} कोई लेना देना नहीं है, लेकिन सब कुछ synchronized{catch{}} या synchronized{} catch{} से कोई लेना देना नहीं है।यह वास्तव में कैच ब्लॉक में आप जो करते हैं उस पर निर्भर करता है।

हालांकि, अनुमान लगाना, InterruptedException के लिए, आपको आमतौर पर synchronized{} के बाहर catch{} करना चाहिए।

2

आपको लगता है कि यह सिर्फ एक सौंदर्य प्रश्न है। यह नहीं है यह एक कार्यात्मक सवाल है और उत्तर प्रत्येक व्यक्तिगत मामले में आवश्यकता से निर्धारित होता है। प्रत्येक सिंक्रनाइज़ ब्लॉक को जितना आवश्यक हो उतना बड़ा होना चाहिए जो कि सिंक्रनाइज़ किए जाने की आवश्यकता हो, और कोई बड़ा नहीं।