2009-03-14 9 views
6

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

कुछ कारणों से process.getInputStream().close() ब्लॉक। जावाडॉक से मैं नहीं देखता कि यह क्यों हो सकता है। इसके अलावा, मुझे समझ में नहीं आता है कि जावडोक कहता है कि "इनपुटस्ट्रीम की करीबी विधि कुछ भी नहीं करती है।" (link to javadoc) क्या कोई इसे समझा सकता है?

धन्यवाद :-)

+0

क्या आप वाकई बाहरी प्रोग्राम के चलते ऐसा नहीं करते हैं? – Geo

उत्तर

4

अवरोधक व्यवहार के संबंध में, जावा में एक ज्ञात समस्या है जो किसी अन्य प्रक्रिया के साथ संवाद करते समय डेडलॉक का कारण बन सकती है। मैं यह नहीं बता सकता कि यह वही है जो आप देख रहे हैं लेकिन यह देखने लायक है। java.lang.Process के लिए दस्तावेज़ का कहना है:

क्योंकि कुछ स्थानीय प्लेटफ़ॉर्म केवल मानक इनपुट और आउटपुट धाराओं के लिए सीमित बफर आकार प्रदान करते हैं, तुरंत इनपुट धारा लिखने या के उत्पादन स्ट्रीम पढ़ें उपप्रक्रिया कारण हो सकता है के लिए विफलता ब्लॉक करने के लिए उपप्रोसेस, और यहां तक ​​कि डेडलॉक।

+0

मैं उसमें देखता हूं, धन्यवाद – Allanrbo

+0

मैं एक ही मुद्दे में भाग गया हूं। क्या सीमित बफर आकार से निपटने का कोई तरीका है और इस प्रकार उपप्रोसे को अवरुद्ध करने से बचें? – JorgeGRC

3

किसी कारण process.getInputStream() के लिए। करीब() ब्लॉक। JavaDoc से मुझे दिखाई नहीं दे रहा है। इसके अलावा, मैं समझ में नहीं आता क्यों जावाडोक "इनपुटस्ट्रीम की करीबी विधि कुछ भी नहीं करती है।" (javadoc से लिंक) कोई इसे समझा सकता है?

यदि आप जावाडोक देखते हैं, तो आप देखेंगे कि इनपुटस्ट्रीम एक सार वर्ग है। इनपुटस्ट्रीम का विस्तार करने वाले उप-वर्गों को निकट() विधि को ओवरराइड करने की उम्मीद है (इसकी आवश्यकता होनी चाहिए)। जाहिर है कि आप जिस इनपुटस्ट्रीम सबक्लास का उपयोग कर रहे हैं वह करीबी विधि में कुछ करता है।

+0

बेशक, यह अच्छी समझ में आता है। मैंने ध्यान नहीं दिया कि इनपुटस्ट्रीम अमूर्त था, धन्यवाद। – Allanrbo

3

जो jdigital लिखा था उस पर जोड़कर, यह article देखें। यह Runtime.exec() विधि से संबंधित है, और ProcessBuilder जावा 5 में पेश किया गया था, लेकिन ऐसा लगता है कि चर्चा सामान्य रूप से सिस्टम प्रक्रियाओं के लिए extrapolated किया जा सकता है।

3

मुझे लगता है कि मैंने इसे समझ लिया। जाहिर है प्रक्रिया.getOutputStream() को बंद करना महत्वपूर्ण है। प्रक्रिया (getInputStream()। करीबी() और process.getErrorStream() बंद करें()।

+0

इनपुट स्ट्रीम से पहले आउटपुट स्ट्रीम को बंद करना क्यों महत्वपूर्ण है? – Michael

+0

क्षमा करें, मेरा मतलब "स्पष्ट रूप से" था। मैंने कभी नहीं सोचा क्यों ... – Allanrbo

+0

धन्यवाद :) मैं इसके बारे में SO पर एक नया प्रश्न पूछूंगा ... – Michael

-1

मुझे एक ही समस्या थी और काफी संघर्ष करने के बाद, एक समाधान मिला, जिसमें का उपयोग Process धाराओं से कुछ भी पढ़ने से पहले होता है। मेरे समाधान का एक स्निपेट here उपलब्ध है।

+0

जिस व्यक्ति ने मतदान किया वह शायद उसके बिंदु को समझा सकता है। –

+0

मैंने आपको कम नहीं किया, लेकिन मुझे नहीं लगता कि यह सही है। कॉलिंग 'उपलब्ध()' आपको बताता है कि जावा पहले से कितना डेटा पढ़ चुका है, या इसके बारे में पता है। ओएस के बफर में यह पूरी तरह से संभव है और जावा को अभी तक उन्हें देखने का मौका नहीं मिला है। एक त्वरित परीक्षण सत्यापित किया गया है कि 'उपलब्ध() 'बहुत लंबी' echo'ed स्ट्रिंग की पूर्ण लंबाई को कैप्चर नहीं करता है। – dimo414