2012-11-24 24 views
8

में IllegalThreadStateException दे रही है जब निम्नलिखित कोड का उपयोग कर रहा IllegalThreadStateException अपवाद हो रही शुरू:बंद करो धागा और फिर ब्लैकबेरी

thread.interrupt(); 
thread.start(); 

लेकिन thread.start()IllegalThreadStateException फेंक रहा है।

इसका समाधान करने के लिए मुझे क्या उपयोग करना चाहिए?

+1

ने अभी 'जावा' टैग जोड़ा, क्योंकि यह किसी भी 'जावा' के लिए आम है। –

उत्तर

16

Thread ऑब्जेक्ट्स केवल एक बार शुरू होने के लिए हैं। आप को रोकने के लिए की जरूरत है/एक Thread बीच में, और फिर इसे फिर से शुरू करना चाहते हैं, तो आप एक नया उदाहरण बनाने चाहिए, और उस पर start() फोन:

thread.interrupt(); // if you need to make sure thread's run() method stops ASAP 
thread = new MyThreadSubclass(); 
thread.start(); 

From the API docs

IllegalThreadStateException - अगर धागा पहले ही शुरू हो चुका था।

मैं जानता हूँ कि यह% नहीं 100 स्पष्ट है कि आप start() फिर से फोन नहीं कर सकते हैं, भले ही आप पहले से interrupt() कहा जाता है, लेकिन यह है कि जिस तरह से यह काम करता है।

यदि आप API docs for standard Java पर देखते हैं, तो यह समस्या अधिक स्पष्ट है।

+0

धन्यवाद नाट। लेकिन जब मैं 'thread.interrupt();' का उपयोग करने की कोशिश कर रहा था यह फिर से अपवाद दिखा रहा है - ** अवैध थ्रेडस्टेट अपवाद **। – AnkitRox

+0

@ एंकिट्रॉक्स, एपीआई दस्तावेज़ यह नहीं दिखाते कि 'इंटरप्ट()' कोई अपवाद फेंकता है। हालांकि, मेरा अनुमान यह होगा कि आप इस कोड को चलाने के पहले बार भी 'इंटरप्ट()' को कॉल कर रहे हैं। यदि आपको एक बार शुरू किया गया है तो आपको वास्तव में केवल थ्रेड को बाधित करने की आवश्यकता होगी। तो, दूसरा, तीसरा, आदि बार आप 'स्टार्ट()' कॉल करना चाहते हैं, तो आप पहले से ही 'इंटरप्ट()' को कॉल कर सकते हैं। 'Thread.interrupt()' को कॉल करने से पहले आप 'thread.isAlive()' का परीक्षण कर सकते हैं। यदि यह काम नहीं करता है, तो आपको कुछ और कोड दिखाना होगा (उदाहरण के लिए आप थ्रेड ऑब्जेक्ट कैसे बनाते हैं)। – Nate

+0

मेरे पास 'AsyncUploadQuestionsAndLeads' के रूप में एक वर्ग है जिसे' थ्रेड 'द्वारा बढ़ाया गया है। का उपयोग करके थ्रेड वस्तु शुरु कर रहा है: 'AsyncUploadQuestionsAndLeads uploadThread = नए AsyncUploadQuestionsAndLeads (घटना),' और कुछ अन्य जगह से धागा शुरू करने: 'uploadThread.start();' कुछ समय के बाद, मैं कर रहा हूँ कोड का उपयोग इस प्रकार करते हुए: 'uploadThread.interrupt(); uploadThread.start(); ' यह मेरी कोड प्रक्रिया है जिसका मैंने पालन किया है। एक और सवाल यह है - क्या थ्रेड स्वयं बंद हो जाता है, जब यह रन रन को पूरा करता है? – AnkitRox

7

नाट के उत्तर के अतिरिक्त।

उसकी टिप्पणी में

AnkitRox कहता है:

धन्यवाद नैट। मैं भी आपकी विधि का प्रयास कर रहा था। लेकिन उस समय समस्या आई थी, यह नए उदाहरण के लिए एक नया धागा शुरू कर दिया गया था और पिछला धागा भी काम कर रहा था।

तो ऐसा लगता है कि समस्या कि "धागा अभी भी चल रहा है, भले ही मैं इस पर बाधा बुलाया"। इस नमूने पर विचार करें (यह बदसूरत है, लेकिन मुख्य विचार को दिखाने के लिए पर्याप्त है):

final Thread t = new Thread(new Runnable() { 
    public void run() { 
     while (true) { 
      for (int i = 0; i < 100000000; i++); // simulate some action 
      System.out.println("hi, interrupted = " 
        + Thread.currentThread().isInterrupted()); 
     } 
    } 
}); 
t.start(); 
new Timer(true).schedule(
    new TimerTask() { 
     public void run() { 
      t.interrupt(); 
     } 
    }, 
    1000 // 1 second delay 
); 

ध्यान दें, धागा के बाद भी interrupt() बुलाया गया है चलाने के लिए जारी है। उत्पादित आउटपुट है:

hi, interrupted = false 
hi, interrupted = true 
hi, interrupted = true 
hi, interrupted = true 
... 
hi, interrupted = true 

दरअसल प्रोग्राम कभी भी बंद नहीं होने तक बंद नहीं होता है। तो फिर interrupt() क्या करता है? यह सिर्फ बाधित से true पर सेट करता है। interrupt() को Thread.currentThread().isInterrupted() कहा जाता है false वापस करने के लिए शुरू होता है। और बस यही।

एक और मामला है, तो interrupt() कहा जाता है, जबकि धागा तरीकों कि फेंक InterruptedException, तो उस विधि InterruptedException फेंक वापस आ जाएगी में से एक की एक मंगलाचरण में अवरुद्ध है है।और अगर थ्रेड कोड सिर्फ "खाती" है कि अपवाद है, तो धागा अभी भी चलते रहेंगे, एक नमूना पर विचार करें:

final Thread t = new Thread(new Runnable() { 
    public void run() { 
     while (true) { 
      System.out.println("hi, interrupted = " 
        + Thread.currentThread().isInterrupted()); 
      try { 
       Thread.sleep(5000); 
      } catch (InterruptedException e) { 
       System.out.println("got InterruptedException"); 
      } 
     } 
    } 
}); 
t.start(); 
new Timer(true).schedule(
    new TimerTask() { 
     public void run() { 
      t.interrupt(); 
     } 
    }, 
    1000 // 1 second delay 
); 

ध्यान दें, धागा के बाद भी interrupt() बुलाया गया है चलाने के लिए जारी है। उत्पादित उत्पादन होता है:

hi, interrupted = false 
got InterruptedException 
hi, interrupted = false 
hi, interrupted = false 
... 
hi, interrupted = false 

ध्यान दें, इस समय interrupted = false के बाद भी interrupt() बुलाया गया है। ऐसा इसलिए है क्योंकि जब भी InterruptedException पकड़ा जाता है, बाधितfalse पर रीसेट किया गया है।

जावा में थ्रेड रोकने से सहकारी तंत्र है। इसका मतलब यह धागे से सहयोग के बिना नहीं किया जा सकता है।

final Thread t = new Thread(new Runnable() { 
    public void run() { 
     while (!Thread.currentThread().isInterrupted()) { 
      System.out.println("hi, interrupted = " 
        + Thread.currentThread().isInterrupted()); 
      try { 
       Thread.sleep(5000); 
      } catch (InterruptedException e) { 
       System.out.println("we've been interrupted"); 
       // restore the interrupted flag 
       Thread.currentThread().interrupt(); 
      } 
     } 
    } 
}); 
t.start(); 
new Timer(true).schedule(
    new TimerTask() { 
     public void run() { 
      t.interrupt(); 
     } 
    }, 
    1000 // 1 second delay 
); 

तो सही दृष्टिकोण समय-समय पर बाधित झंडा जांच करने के लिए किया जाना चाहिए: यहाँ ऊपर नमूने की तय संस्करण है। और यदि बाधित स्थिति का पता चला है तो बस ASAP वापस करें। एक अन्य आम विकल्प Thread.interrupt() का उपयोग नहीं करना है, लेकिन some custom boolean instead

+0

महान स्पष्टीकरण। बिल्कुल बदसूरत नहीं :) – Nate

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