2013-07-30 4 views
5

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

मेरा पहला विचार यह था कि यह कैसे करना है बच्चे को धागा बनाना और वह नींद रखना और फिर सफाई करना। लेकिन तब जब पैरेंट थ्रेड अभी भी दौड़ने की कोशिश कर रहा है और ऐसा नहीं हो सकता है तो यह एक त्रुटि आउटपुट करता है।

+0

क्या इस धागे में शीर्ष स्तर का लूप है? क्या कोड का एक टुकड़ा है जो थ्रेड हो जाता है भले ही थ्रेड फंस जाए? क्या आप भविष्यवाणी कर सकते हैं कि काम शुरू होने से पहले कितनी बार थ्रेड लूप/रिकर्स होगा? –

+0

आदर्श रूप से, आपके पास कुछ झंडा होना चाहिए जो आपका थ्रेड समय-समय पर जांच करता है। यदि ध्वज सेट किया गया है, तो आपके धागे को इसके कार्य के व्यवस्थित शटडाउन का संचालन करना चाहिए। – Aurand

+0

कोई लूप या कुछ भी नहीं है। धागा डेटा भेजता है लेकिन यदि डेटा भेजने के लिए बहुत लंबा समय लगता है तो मैं इसे बंद करना चाहता हूं। अगर यह कोड की एक पंक्ति पर फंस गया है तो मैं समय-समय पर जांच कैसे कर सकता हूं? – user760220

उत्तर

3

अपने कोड को कॉल करने योग्य में रीफैक्टर करें और भविष्य प्राप्त करने के लिए एक्जिक्यूटर्स सेवा का उपयोग करें। फिर एक टाइमआउट के साथ उपयोग करें, जो तब तक टाइमआउट अपवाद फेंकता है यदि तब तक नहीं किया जाता है। एक पूर्ण उदाहरण के लिए https://stackoverflow.com/a/2275596/53897 देखें।

+0

मैं पूरी तरह से भविष्य के बारे में भूल गया। +1 –

+1

यह सक्रिय धागा मरने का कारण नहीं है। केवल प्रतीक्षा धागा जिसने 'भविष्य.get (लंबा, टाइमयूनीट)' शुरू किया था। कार्य निष्पादित किया जा रहा है। – yair

+0

फिर निष्पादक को बंद करने के लिए कहें। –

0

आपको अपनी अवरुद्ध कॉल के लिए टाइमआउट सेट करने की आवश्यकता है। यदि कोई टाइमआउट नहीं है, तो इस तरह से कॉल करें और समय निकाल दें।

आप अपनी समापन स्थिति के लिए कार्य को 1 धागा बना सकते हैं, और अगर इसे कुछ मूल्य से अधिक हो तो इसे मार दें। कार्य को अभी भी एक और धागे की आवश्यकता होगी। मैं ऐसा कार्य करके ऐसा करूँगा जिसमें staleness मान हो। समय-समय पर सभी कार्यों को मतदान करें, अगर वे बासी हैं, तो उन्हें रद्द करें।

0

सुझाव 1: यदि आप अपने कोड को प्रतीक्षा() कथन के साथ एक कोशिश ब्लॉक में डालते हैं तो आप अंतःस्थापित अपवाद को पकड़ सकते हैं जो आपके अंत में अनुसरण करेगा। जब भी परिस्थितियों को आपके धागे को बाधित करने की आवश्यकता होती है तो बाधा उत्पन्न करने के लिए एक अन्य थ्रेड को अधिसूचना() या सूचित करें() को भेजना होगा।

सुझाव 2: मैं केवल जावा के साथ एक शुरुआत करने वाला हूं लेकिन थ्रेड फेंकने का मतलब है कि आप अपने प्रयास/अंत में ब्लॉक के अंदर एक कस्टम अपवाद फेंकने में सक्षम होना चाहिए।

+0

आपको जावा 5 दिलचस्प समवर्ती परिवर्धन मिल सकता है। धागे का उपयोग करना 100% सही करना मुश्किल है। –

0

(1)

बेस्ट समाधान एक टाइमआउट के साथ अपने डेटा भेजने के लिए है। जैसे

try { 
    mySendingDataLibraryApi.sendData(data, timeout /*, timeUnit */); 
     // some new APIs enable also to configure the time unit of the required timeout. 
     // Older APIs typically just use milliseconds. 
} catch (TimeoutException e) { 
    doCleanup(); // your cleanup method. 
} 

(2)

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

class MySendingDataRunnable implements Runnable {  
    @Override 
    public void run() { 
     try { 
      mySendingDataLibraryApi.sendDataInterruptibly(data); 
     } catch (InterruptedException e) { 
      doCleanup(); // your cleanup method. 
      // here either re-throw InterruptedExecption 
      // or restore the interrupted state with Thread.currentThread().interrupt(); 
     } 
    } 
} 

: मैं इस तरह के एक विधि के अस्तित्व पर ज्यादा भरोसा नहीं होता है, तो एक समय विधि एपीआई द्वारा प्रदान नहीं की है ... वैसे भी, थ्रेड में कोड उस कार्य को निष्पादित करता दिखाई देगा फोन करने वाले में कोड धागा, एक ExecutorService और Future उदाहरण, अपना Future<?> submit(Runnable task) विधि द्वारा वापस का उपयोग करना चाहिए आदेश mayInterruptIfRunning तर्क true करने के लिए सेट के साथ वांछित समय प्रतीक्षा करें और कार्य को रद्द करने के लिए:

final ExecutorService executor = Executors.newSingleThreadExecutor(); 
final Future<?> future = executor.submit(new MySendingDataRunnable()); 
try { 
    final Object noResult = future.get(60, TimeUnit.SECONDS); // no result for Runnable 
} catch (InterruptedException e) { 
    // here again either re-throw or restore interupted state 
} catch (ExecutionException e) { 
    // some applicative exception has occurred and should be handled 
} catch (TimeoutException e) { 
    future.cancel(true); // *** here you actually cancel the task after time is out 
} 

(3)

यदि आपके द्वारा उपयोग की जाने वाली एपीआई इनमें से किसी भी सुविधा (समय/इंटरप्टिबल विधियों) प्रदान नहीं करती है, तो आपको अपनी रचनात्मकता का उपयोग करना होगा! आपके संसाधन को अवरुद्ध करने की यह एक पंक्ति को कुछ संसाधन पर अवरुद्ध करनी चाहिए। इस संसाधन के लिए पहुंचने का प्रयास करें और इसे बंद कर दें या इससे डिस्कनेक्ट करें, जिससे कार्य को समाप्त कर दिया जा सके।एक सामान्य उदाहरण नेटवर्क कनेक्शन बंद कर रहा है।


नोट: ऊपर समाधान केवल वास्तव में कार्य रद्द किए जाने और आगे कार्यों के लिए धागा मुक्त कराने का एक तरीका प्रदान करते हैं। धागा अभी भी जिंदा हो सकता है। थ्रेड को मारना आम तौर पर ऐसा नहीं होता है जब कोई कार्य पूरा हो जाता है (या उस मामले में विफल रहता है)। यह स्वीकार्य है जब आपने विशिष्ट कार्य (ओं) के लिए कुछ धागे बनाए हैं जिन्हें कभी भी निष्पादित नहीं किया जाना चाहिए। ऐसे मामलों में आप उपर्युक्त ExecutorService का उपयोग करते हैं और इसकी shutdownNow() विधि का आह्वान करते हैं। और यहां तक ​​कि shutdownNow() केवल सबसे अच्छा प्रयास करता है और आम तौर पर वास्तविक कार्य पर निर्भर करता है व्यवधान कारक होने के लिए ...

Here's a detailed article (कुछ हद तक पुराने लेकिन फिर भी)।

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