java सकत क्या एक ही थ्रेड पर दो बार स्टार्ट विधि को कॉल करना कानूनी है?




सम्मेलन कॉल (8)

निम्न कोड java.lang.IllegalThreadStateException: Thread already started ओर जाता है java.lang.IllegalThreadStateException: Thread already started जब मैंने प्रोग्राम में start() विधि को दूसरी बार बुलाया था तब java.lang.IllegalThreadStateException: Thread already started हो गया था।

updateUI.join();    

if (!updateUI.isAlive()) 
    updateUI.start();

यह दूसरी बार updateUI.start() कहा जाता है। मैंने इसे कई बार कदम रखा है और थ्रेड को बुलाया जाता है और updateUI.start() मारने से पहले पूरी तरह से पूरा करने के लिए चला जाता है।

कॉलिंग updateUI.run() त्रुटि से बचाता है लेकिन थ्रेड को यूआई थ्रेड में चलाता है (कॉलिंग थ्रेड, जैसा कि एसओ पर अन्य पोस्ट में उल्लिखित है), जो मैं नहीं चाहता हूं।

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


बिल्कुल सही। दस्तावेज़ीकरण से :

धागे को एक से अधिक बार शुरू करना कभी कानूनी नहीं होता है। विशेष रूप से, निष्पादन पूरा होने के बाद, थ्रेड को पुनरारंभ नहीं किया जा सकता है।

बार-बार गणना के लिए आप क्या कर सकते हैं, इस तरह ऐसा लगता है कि आप स्विंग यूटिलिटीज इनोकोकलेटर विधि का उपयोग कर सकते हैं। आप पहले ही कॉलिंग run() सीधे प्रयोग कर रहे हैं, जिसका अर्थ है कि आप कच्चे Thread बजाय Runnable का उपयोग करने के बारे में सोच रहे हैं। केवल invokeLater कार्य पर invokeLater विधि का उपयोग करने का प्रयास करें और देखें कि क्या यह आपके मानसिक पैटर्न को थोड़ा बेहतर बनाता है या नहीं।

दस्तावेज़ीकरण से उदाहरण यहां दिया गया है:

 Runnable doHelloWorld = new Runnable() {
     public void run() {
         // Put your UI update computations in here.
         // BTW - remember to restrict Swing calls to the AWT Event thread.
         System.out.println("Hello World on " + Thread.currentThread());
     }
 };

 SwingUtilities.invokeLater(doHelloWorld);
 System.out.println("This might well be displayed before the other message.");

यदि आप अपनी गणना के साथ उस println कॉल को प्रतिस्थापित करते हैं, तो यह वही हो सकता है जो आपको चाहिए।

संपादित करें: टिप्पणी के बाद, मैंने मूल पोस्ट में एंड्रॉइड टैग नहीं देखा था। एंड्रॉइड काम में Handler.post(Runnable) करने के बराबर Handler.post(Runnable) । अपने जावाडोक से:

/**
 * Causes the Runnable r to be added to the message queue.
 * The runnable will be run on the thread to which this handler is
 * attached.
 *
 * @param r The Runnable that will be executed.
 *
 * @return Returns true if the Runnable was successfully placed in to the
 *         message queue.  Returns false on failure, usually because the
 *         looper processing the message queue is exiting.
 */

तो, एंड्रॉइड दुनिया में, आप उपरोक्त के समान उदाहरण का उपयोग कर सकते हैं, एक Handler को उपयुक्त पोस्ट के साथ Swingutilities.invokeLater को बदल सकते हैं।


हां हम पहले से ही थ्रेड चलाना शुरू नहीं कर सकते हैं। यह रनटाइम पर IllegalThreadStateException फेंक देगा - अगर धागा पहले ही शुरू हो गया था।

क्या होगा यदि आपको वास्तव में थ्रेड प्रारंभ करने की आवश्यकता है: विकल्प 1) यदि किसी थ्रेड को एक से अधिक बार चलाने की आवश्यकता है, तो किसी को थ्रेड का एक नया उदाहरण बनाना चाहिए और उस पर कॉल करना चाहिए।


यह वास्तव में बदसूरत होगा लेकिन आप इसके लिए कोड चलाने के लिए एक थ्रेड के साथ एक थ्रेड लपेट सकते हैं, लेकिन केवल यह करना है कि आपको वास्तव में करना है।

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


Thread.start विधि के लिए जावा एपीआई विशिष्टता से :

धागे को एक से अधिक बार शुरू करना कभी कानूनी नहीं होता है। विशेष रूप से, निष्पादन पूरा होने के बाद, थ्रेड को पुनरारंभ नहीं किया जा सकता है।

इसके अलावा:

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

तो हाँ, एक Thread केवल एक बार शुरू किया जा सकता है।

यदि मैं थ्रेड को फिर से चलाने के लिए करता हूं तो मैं क्या करूँ?

यदि किसी Thread को एक से अधिक बार चलाने की आवश्यकता है, तो किसी को Thread का एक नया उदाहरण बनाना चाहिए और उस पर कॉल start करना चाहिए।


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


नहीं , हम फिर से थ्रेड शुरू नहीं कर सकते हैं, ऐसा करने से runtimeException java.lang.IleglegalTreadStateException फेंक देगा। >

कारण एक बार चलाया जाता है () विधि थ्रेड द्वारा निष्पादित की जाती है, यह मृत राज्य में जाती है।

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

public class MyClass implements Runnable{

    @Override
    public void run() {
           System.out.println("in run() method, method completed.");
    }

    public static void main(String[] args) {
                  MyClass obj=new MyClass();            
        Thread thread1=new Thread(obj,"Thread-1");
        thread1.start();
        thread1.start(); //will throw java.lang.IllegalThreadStateException at runtime
    }

}

/ * रन () विधि में आउटपुट, विधि पूर्ण हो गई। थ्रेड में अपवाद "मुख्य" java.lang.IleglegalhreadStateException java.lang.Thread.start (अज्ञात स्रोत) * /

इसे देखो


आपको क्या करना चाहिए एक रननेबल बनाएं और प्रत्येक बार जब आप रननेबल को चलाने के लिए एक नए थ्रेड के साथ लपेटें। यह वास्तव में बदसूरत होगा लेकिन आप इसके लिए कोड चलाने के लिए एक थ्रेड के साथ एक थ्रेड लपेट सकते हैं, लेकिन केवल यह करना है कि आपको वास्तव में करना है।


अभी पहुंचने वाले उत्तर में शामिल हैं कि आपको ऐसा क्यों नहीं करना चाहिए जो आप कर रहे हैं। आपकी वास्तविक समस्या को हल करने के लिए यहां कुछ विकल्प दिए गए हैं।

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

अपना खुद का धागा डंप करें और AsyncTask उपयोग AsyncTask

या जब आपको इसकी आवश्यकता हो तो ताज़ा धागा बनाएं।

या धागे को पुनरारंभ करने के बजाय एक कार्य कतार (उदाहरण के लिए, LinkedBlockingQueue ) से बाहर निकलने के लिए अपना धागा सेट करें।





multithreading