Le code suivant mène au java.lang.IllegalThreadStateException: Thread already started
moment où j'ai appelé la start()
méthode une deuxième fois dans le programme.
updateUI.join();
if (!updateUI.isAlive())
updateUI.start();
Cela se produit la deuxième fois updateUI.start()
est appelée. Je l'ai parcouru plusieurs fois et le thread est appelé et se termine complètement avant de frapper updateUI.start()
.
L'appel updateUI.run()
évite l'erreur mais provoque l'exécution du thread dans le thread de l'interface utilisateur (le thread appelant, comme mentionné dans d'autres articles sur SO), ce qui n'est pas ce que je veux.
Un fil de discussion peut-il être démarré une seule fois? Si tel est le cas, que dois-je faire si je veux relancer le fil? Ce thread particulier fait un calcul en arrière-plan, si je ne le fais pas dans le thread, c'est fait dans le thread de l'interface utilisateur et que l'utilisateur a une attente déraisonnablement longue.
la source
Réponses:
À partir de la spécification de l'API Java pour la
Thread.start
méthode:En outre:
Alors oui, a
Thread
ne peut être démarré qu'une seule fois.Si a
Thread
doit être exécuté plus d'une fois, il faut créer une nouvelle instance deThread
et l'appelerstart
.la source
Thread
chaque fois. Au lieu de cela, il devrait soumettre la tâche à un pool de threads (par exemplejava.util.concurrent.ThreadPoolExecutor
)Exactement raison. De la documentation :
En ce qui concerne ce que vous pouvez faire pour des calculs répétés, il semble que vous puissiez utiliser la méthode SwingUtilities invokeLater . Vous expérimentez déjà l'appel
run()
direct, ce qui signifie que vous envisagez déjà d'utiliser unRunnable
plutôt qu'un brutThread
. Essayez d'utiliser lainvokeLater
méthode uniquement sur laRunnable
tâche et voyez si cela correspond un peu mieux à votre schéma mental.Voici l'exemple de la documentation:
Si vous remplacez cet
println
appel 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 d'origine. L'équivalent d'invokeLater dans le travail Android est
Handler.post(Runnable)
. Depuis son javadoc:Ainsi, dans le monde Android, vous pouvez utiliser le même exemple que ci-dessus, en remplaçant le
Swingutilities.invokeLater
par le post approprié dans un fichierHandler
.la source
RunOnUIThread(Runnable)
ouView.post(Runnable)
au lieu de créer votre propre gestionnaire. Ceux-ci exécuteront le runnable sur le thread principal vous permettant de mettre à jour l'interface utilisateur.La réponse qui vient d'arriver explique pourquoi vous ne devriez pas faire ce que vous faites. Voici quelques options pour résoudre votre problème réel.
Videz votre propre fil et utilisez-le
AsyncTask
.Ou créez un nouveau fil lorsque vous en avez besoin.
Ou configurez votre thread pour qu'il fonctionne à partir d'une file d'attente de travail (par exemple
LinkedBlockingQueue
) plutôt que de redémarrer le thread.la source
Non , nous ne pouvons pas redémarrer Thread, cela lèvera runtimeException java.lang.IllegalThreadStateException. >
Prenons un exemple - Penser à redémarrer le thread et à appeler la méthode start () dessus (qui en interne va appeler la méthode run ()) pour nous, c'est comme demander à un homme mort de se réveiller et de courir. Comme, après avoir terminé sa vie, la personne passe à l'état mort.
vérifie ça
la source
Ce que vous devez faire est de créer un Runnable et de l'envelopper avec un nouveau Thread à chaque fois que vous souhaitez 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 ne le faites que si vous le devez vraiment.
la source
Comme vous l'avez dit, un thread ne peut pas être démarré plus d'une fois.
Directement de la bouche du cheval: Java API Spec
Si vous avez besoin de réexécuter tout ce qui se passe dans votre thread, vous devrez créer un nouveau thread et l'exécuter.
la source
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 à nouveau.
la source
Oui, nous ne pouvons pas démarrer déjà le thread. Il lèvera IllegalThreadStateException au moment de l'exécution - si le thread a déjà été démarré.
Que faire si vous avez vraiment besoin de démarrer le thread: Option 1) Si un thread doit être exécuté plus d'une fois, alors il faut créer une nouvelle instance du thread et appeler start dessus.
la source
Oui. Vous pouvez le démarrer exactement une fois.
Ne
Thread
recommencez pas. Créez plutôt Runnable et publiez-le sur Handler of HandlerThread . Vous pouvez soumettre plusieursRunnable
objets. Si vous souhaitez renvoyer des données à UI Thread, avec votreRunnable
run()
méthode, publiez unMessage
surHandler
UI Thread et traitezhandleMessage
Reportez-vous à cet article pour un exemple de code:
Android: Toast dans un fil
la source
Je ne sais pas si c'est une bonne pratique, mais quand je laisse run () être appelé dans la méthode run (), cela ne génère aucune erreur et fait exactement ce que je voulais.
Je sais que cela ne recommence pas un fil, mais peut-être que cela vous sera utile.
J'espère que cela aide, même si c'est juste un peu.
À votre santé
la source
J'ai dû réparer une fuite de ressources causée par un programmeur qui a créé un Thread mais au lieu de le démarrer (), il a appelé directement la méthode run (). Alors évitez-le, sauf si vous savez vraiment quels effets secondaires cela provoque.
la source
run()
directement, mais simplement d'incorporer un Runnable dans un Thread et vraisemblablement l'invoquerstart()
.