Est-il légal d’appeler la méthode de démarrage deux fois sur le même thread?

Le code suivant conduit à java.lang.IllegalThreadStateException: Thread already started lorsque j’ai appelé la méthode start() deuxième fois dans le programme.

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

Cela se produit la deuxième fois que updateUI.start() est appelée. Je l’ai parcouru plusieurs fois et le thread est appelé et s’exécute complètement avant de updateUI.start() .

L’appel de updateUI.run() évite l’erreur mais provoque l’exécution du thread dans le thread d’interface utilisateur (le thread appelant, comme mentionné dans d’autres publications sur SO), ce qui n’est pas ce que je veux.

Un fil ne peut-il être démarré qu’une seule fois? Si oui, que dois-je faire si je veux relancer le thread? Ce thread en particulier fait des calculs en arrière-plan, si je ne le fais pas dans le thread que dans le thread d’interface utilisateur et que l’utilisateur a une attente excessivement longue.

A partir de la spécification de l’API Java pour la méthode Thread.start :

Il n’est jamais légal de démarrer une discussion plus d’une fois. En particulier, un thread ne peut pas être redémarré une fois l’exécution terminée.

En outre:

Jette:
IllegalThreadStateException – si le thread a déjà été démarré.

Alors oui, un Thread ne peut être lancé qu’une seule fois.

Si oui, que dois-je faire si je veux relancer le thread?

Si un Thread doit être exécuté plusieurs fois, il convient alors de créer une nouvelle instance du Thread et d’appeler dessus.

Exactement exact. De la documentation :

Il n’est jamais légal de démarrer une discussion plus d’une fois. En particulier, un thread ne peut pas être redémarré une fois l’exécution terminée.

En ce qui concerne ce que vous pouvez faire pour le calcul répété, il semble que vous puissiez utiliser la méthode invokeLater de SwingUtilities . Vous essayez déjà d’appeler directement run() , ce qui signifie que vous envisagez déjà d’utiliser un Thread Runnable plutôt qu’un Thread brut. Essayez d’utiliser la méthode invokeLater sur la tâche Runnable et voyez si cela correspond mieux à votre schéma mental.

Voici l’exemple de la documentation:

  Runnable doHelloWorld = new Runnable() { public void run() { // Put your UI update computations in here. // BTW - remember to ressortingct 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."); 

Si vous remplacez cet appel println par votre calcul, il se peut que ce soit exactement ce dont vous avez besoin.

EDIT: suite au commentaire, je n’avais pas remarqué la balise Android dans le message original. L’équivalent de invokeLater dans le travail Android est Handler.post(Runnable) . De son javadoc:

 /** * 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. */ 

Ainsi, dans le monde Android, vous pouvez utiliser le même exemple que ci-dessus, en remplaçant le Swingutilities.invokeLater par le message approprié dans un Handler .

La réponse juste-arrivée explique pourquoi vous ne devriez pas faire ce que vous faites. Voici quelques options pour résoudre votre problème actuel.

Ce thread en particulier fait des calculs en arrière-plan, si je ne le fais pas dans le thread que dans le thread d’interface utilisateur et que l’utilisateur a une attente excessivement longue.

Videz votre propre thread et utilisez AsyncTask .

Ou créez un nouveau fil quand vous en avez besoin.

Ou configurez votre thread pour qu’il fonctionne à partir d’une queue de travail (par exemple, LinkedBlockingQueue ) plutôt que de redémarrer le thread.

Non , nous ne pouvons pas démarrer Thread à nouveau, car cela lancera runtimeException java.lang.IllegalThreadStateException. >

La raison en est que lorsque la méthode run () est exécutée par Thread, elle passe en état mort.

Prenons un exemple – Penser à relancer le thread et appeler la méthode start () (qui en interne va appeler la méthode run ()) est pour nous quelque chose comme demander à un homme mort de se réveiller et de s’exécuter. Comme, après avoir terminé sa vie, la personne passe à l’état mort.

 public class MyClass implements Runnable{ @Override public void run() { System.out.println("in run() method, method completed."); } public static void main(Ssortingng[] args) { MyClass obj=new MyClass(); Thread thread1=new Thread(obj,"Thread-1"); thread1.start(); thread1.start(); //will throw java.lang.IllegalThreadStateException at runtime } } 

/ * OUTPUT dans la méthode run (), méthode terminée. Exception dans le thread “main” java.lang.IllegalThreadStateException à java.lang.Thread.start (source inconnue) * /

vérifie ça

Ce que vous devez faire est de créer un Runnable et de l’envelopper avec un nouveau thread chaque fois que vous voulez exécuter le Runnable. Ce serait vraiment moche à faire, mais vous pouvez envelopper un thread avec un autre thread pour exécuter à nouveau le code, mais seulement vous devez vraiment.

C’est comme vous l’avez dit, un thread ne peut être lancé plus d’une fois.

Directement de la bouche du cheval: Java API Spec

Il n’est jamais légal de démarrer une discussion plus d’une fois. En particulier, un thread ne peut pas être redémarré une fois l’exécution terminée.

Si vous avez besoin de relancer ce qui se passe dans votre thread, vous devrez créer un nouveau thread et l’exécuter.

Réutiliser un thread est une action illégale dans l’API Java. Cependant, vous pouvez l’envelopper dans un outil exécutable et réexécuter cette instance.

Oui, nous ne pouvons pas déjà lancer le thread. Il lancera une exception IllegalThreadStateException à l’exécution – si le thread a déjà été démarré.

Que faire si vous avez vraiment besoin de démarrer un thread: Option 1) Si un thread doit être exécuté plusieurs fois, il convient alors de créer une nouvelle instance du thread et d’appeler dessus.

Un fil ne peut-il être démarré qu’une seule fois?

Oui. Vous pouvez le démarrer exactement une fois.

Si oui, que dois-je faire si je veux relancer le thread? Ce thread particulier fait des calculs en arrière-plan, si je ne le fais pas dans le thread que dans le thread de l’interface utilisateur et que l’utilisateur a un déraisonnable une longue attente.

Ne lancez pas le Thread nouveau. Au lieu de cela, créez Runnable et publiez-le sur Handler of HandlerThread . Vous pouvez soumettre plusieurs objects Runnable . Si vous souhaitez renvoyer des données au thread d’interface utilisateur, avec votre méthode Runnable run() , publiez un Message sur le Handler de thread d’interface utilisateur et traitez handleMessage

Reportez-vous à cet article pour un exemple de code:

Android: Toast dans un fil

Ce serait vraiment moche à faire, mais vous pouvez envelopper un thread avec un autre thread pour exécuter à nouveau le code, mais seulement vous devez vraiment.

J’ai dû réparer une fuite de ressource causée par un programmeur qui a créé un thread, mais au lieu de le lancer (), il a directement appelé la méthode run (). Alors évitez-le, à moins que vous ne sachiez vraiment quels effets secondaires il provoque.