2010-04-28 16 views
5

यह प्रश्न मुझे थोड़ी देर के लिए नाचता है लेकिन मुझे अभी तक इसका पूरा जवाब नहीं मिला है (उदाहरण के लिए यह सी # Initializing disposable resources outside or inside try/finally के लिए है)। पर विचार दो निम्नलिखित जावा कोड के टुकड़े:जावा अंत में बदलावों का प्रयास करें

Closeable in = new FileInputStream("data.txt"); 
try { 
    doSomething(in); 
} finally { 
    in.close(); 
} 

और दूसरी भिन्नता

Closeable in = null; 
try { 
    in = new FileInputStream("data.txt"); 
    doSomething(in); 
} finally { 
    if (null != in) in.close(); 
} 

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

  1. InterruptedException (जैसे थ्रेड # बाधा के माध्यम से()) या OutOfMemoryError अपवाद (जैसे के माध्यम से मार डालते हैं, फेंक दिया जाता है
  2. JVM बाहर निकलता है प्रणाली। बाहर निकलने के())
  3. हार्डवेयर पूरी सूची :) के लिए असफल (या JVM में बग

मैंने पढ़ा है कि दूसरा दृष्टिकोण कुछ अधिक "मुहावरेदार" है, लेकिन IMO परिदृश्य में ऊपर वहाँ कोई अंतर नहीं है और अन्य सभी में परिदृश्य वे बराबर हैं।

तो सवाल:

क्या दोनों के बीच अंतर कर रहे हैं? अगर मुझे संसाधनों को मुक्त करने के बारे में चिंतित है (विशेष रूप से भारी बहु थ्रेडिंग अनुप्रयोगों में) तो मुझे कौन सा प्राथमिकता देना चाहिए? क्यूं कर?

अगर कोई मुझे जावा/जेवीएम चश्मे के कुछ हिस्सों को इंगित करता है तो मैं जवाब दूंगा।

उत्तर

6

मुझे नहीं लगता कि ऐसा कोई कारण चिंतित होने की है: एक ऐसी ही चर्चा यहाँ देखें

1) InterruptedException (जैसे के माध्यम से धागा # बाधा())

कॉलिंग Thread.interrupt()InterruptedException को स्वचालित रूप से फेंकने का कारण नहीं है। अपवाद केवल विशिष्ट (और अच्छी तरह से प्रलेखित) अवरुद्ध विधियों के भीतर फेंक दिया जाता है; यानी I/O अवरुद्ध करना और सिंक्रनाइज़ेशन विधियां। स्ट्रीम अपरेटर से लौटने के बाद और कोशिश ब्लॉक में प्रवेश करने से पहले यह अपवाद नहीं फेंक दिया जा सकता है।

या OutOfMemoryError अपवाद

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

2) JVM बाहर निकलता है (उदाहरण के लिए के माध्यम से मार डालते हैं, System.exit())

आवेदन जबरन एक बाहरी kill या एक System.exit() कॉल द्वारा समाप्त किया जा रहा है, तो यह कोई फर्क नहीं पड़ता अगर धाराएं हैं ठीक से बंद कर दिया। इसके अलावा, दोनों मामलों में इस बात की कोई गारंटी नहीं है कि अंत में खंडों को निष्पादित किया जाएगा।

3) हार्डवेयर पूरी सूची के लिए असफल (या बग JVM में :)

सभी दांव बंद कर रहे हैं। आपके पास कुछ भी निष्पादित करने का कोई तरीका नहीं है, आखिरकार आखिरकार ब्लॉक करें।

एक और स्थिति है जहां थ्रेड को उस बिंदु पर एक स्वचालित अपवाद प्राप्त हो सकता है, जिसमें कुछ (बेवकूफ) उम्मीद है कि यह ठीक हो सकता है। वह तब होता है जब कुछ गुमराह प्रोग्रामर बहिष्कृत Thread.stop() विधि को कॉल करने का निर्णय लेता है। आपको लगता है कि try ब्लॉक के अंदर स्ट्रीम कन्स्ट्रक्टर कॉल डालने से मदद मिलेगी। लेकिन वास्तव में यह नहीं होगा, क्योंकि ThreadDeath अपवाद अंतर्निहित फ़ाइल खोलने और स्ट्रीम ऑब्जेक्ट के निर्माण को पूरा करने के बीच स्ट्रीम कंस्ट्रक्टर के रूप में उठाया जा सकता है। तो एफडी वैसे भी रिसाव कर सकता है।

यह एक कारण है कि Thread.stop() को बहिष्कृत किया गया है। इसका इस्तेमाल न करें।

0

मेरा विचार है कि अपने खास सवाल की तरह चीजों के साथ चिंता का विषय अपने आप को जाता है जब आप जैसे कि जावा या .NET तुम सच में नहीं करना चाहिए, एक प्रबंधित क्रम के साथ काम कर रहे हैं (और यह अच्छा है!)। केवल इसलिए कि आप पूरी तरह से अंतर्निहित ऑपरेटिंग सिस्टम और इसके मूल एपीआई से डिस्कनेक्ट हैं। आपको बस इतना पता होना है कि आप अपने finally ब्लॉक में Closable.close() पर कॉल करते हैं और आपका संसाधन हमेशा मुक्त हो जाएगा।

+0

जब तक आप प्रयास ब्लॉक में संसाधन प्राप्त करते हैं ... – pgras

+0

दुर्भाग्य से "प्रबंधित" का अर्थ है कि यह संसाधन प्रबंधन समस्याओं का एक हिस्सा हल करता है (हालांकि एक बड़ा)। यदि आप बहुत सारे संसाधनों को प्राप्त करते हैं तो आपको अभी भी उन्हें जारी करने का ख्याल रखना चाहिए क्योंकि आमतौर पर उनमें सीमित मात्रा होती है। और हाँ, ताले हैं। और deadlocks। –

+0

@pgras आप 'try' block में संसाधन क्यों प्राप्त करना चाहते हैं ?? यह सिर्फ आपके कोड की गड़बड़ी करता है। –

5

ए) ध्यान दें कि थ्रेड में बाधा डालने से इंटरप्ट() तुरंत प्रभावी नहीं होगा, और अगर कोई थ्रेड बाधित नहीं होता है तो इसका कोई प्रभाव नहीं पड़ता है।

Closeable in = new FileInputStream("data.txt"); 

केवल बात यह है कि क्या होगा है कि धागे के अपने बाधित झंडा चालू हो जाएगा: कोई रास्ता नहीं धागा() के निष्पादन के दौरान बीच में होने के कारण बाहर निकल जाएगा नहीं है।

बी) OutOfMemoryError के संबंध में - मुझे नहीं लगता कि इनपुट स्ट्रीम के निर्माण के बाद यह कैसे हो सकता है। यह किसी अन्य धागे में हो सकता है, लेकिन इसका इस धागे पर कोई तत्काल प्रभाव नहीं पड़ेगा। OutOfMemoryError के साथ समस्या यह है कि आपका आखिरकार ब्लॉक भी असफल हो सकता है, क्योंकि इसे पूरा करने के लिए पर्याप्त स्मृति नहीं है ...

सी) एकमात्र तरीका मुझे पता है कि थ्रेड को आक्रामक तरीके से बाधित किया जा सकता है, बहिष्कृत विधियों का उपयोग कर रहा है .stop() और थ्रेड.स्टॉप (थ्रोबल)। Is this a safe way to release resources in Java?

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