Der folgende Code führt dazu, java.lang.IllegalThreadStateException: Thread already started
dass ich die start()
Methode zum zweiten Mal im Programm aufgerufen habe .
updateUI.join();
if (!updateUI.isAlive())
updateUI.start();
Dies geschieht , das zweite Mal updateUI.start()
aufgerufen wird. Ich habe es mehrmals durchlaufen und der Thread wird aufgerufen und läuft vollständig bis zum Abschluss, bevor er getroffen wird updateUI.start()
.
Das Aufrufen updateUI.run()
vermeidet den Fehler, führt jedoch dazu, dass der Thread im UI-Thread ausgeführt wird (der aufrufende Thread, wie in anderen Beiträgen zu SO erwähnt), was ich nicht möchte.
Kann ein Thread nur einmal gestartet werden? Wenn ja, was mache ich, wenn ich den Thread erneut ausführen möchte? Dieser bestimmte Thread führt einige Berechnungen im Hintergrund durch, wenn ich dies nicht im Thread als im UI-Thread mache und der Benutzer eine unangemessen lange Wartezeit hat.
quelle
Antworten:
Aus der Java-API-Spezifikation für die
Thread.start
Methode:Außerdem:
Also ja, a
Thread
kann nur einmal gestartet werden.Wenn a
Thread
mehr als einmal ausgeführt werden muss, sollte eine neue Instanz von erstelltThread
und aufgerufen werdenstart
.quelle
Thread
jedes Mal eine neue erstellen . Stattdessen sollte es die Aufgabe an einen Thread-Pool (z. B.java.util.concurrent.ThreadPoolExecutor
) sendenGenau richtig. Aus der Dokumentation :
In Bezug auf das, was Sie für wiederholte Berechnungen tun können, scheint es, als könnten Sie die SwokeUtilities-Methode invokeLater verwenden . Sie experimentieren bereits mit dem
run()
direkten Anrufen , was bedeutet, dass Sie bereits darüber nachdenken,Runnable
ein Raw anstelle eines Raw zu verwendenThread
. Versuchen Sie, dieinvokeLater
Methode nur für dieRunnable
Aufgabe zu verwenden, und prüfen Sie, ob dies etwas besser zu Ihrem mentalen Muster passt.Hier ist das Beispiel aus der Dokumentation:
Wenn Sie diesen
println
Aufruf durch Ihre Berechnung ersetzen, ist er möglicherweise genau das, was Sie benötigen.BEARBEITEN: Nach dem Kommentar hatte ich das Android-Tag im ursprünglichen Beitrag nicht bemerkt. Das Äquivalent zu invokeLater in der Android-Arbeit ist
Handler.post(Runnable)
. Aus seinem Javadoc:In der Android-Welt können Sie also dasselbe Beispiel wie oben verwenden und das
Swingutilities.invokeLater
durch den entsprechenden Beitrag in a ersetzenHandler
.quelle
RunOnUIThread(Runnable)
oderView.post(Runnable)
zu erstellen. Diese führen die ausführbare Datei im Hauptthread aus, sodass Sie die Benutzeroberfläche aktualisieren können.Die gerade eingetroffene Antwort behandelt, warum Sie nicht tun sollten, was Sie tun. Hier sind einige Optionen zur Lösung Ihres eigentlichen Problems.
Dump deinen eigenen Thread und benutze
AsyncTask
.Oder erstellen Sie einen neuen Thread, wenn Sie ihn benötigen.
Oder richten Sie Ihren Thread so ein, dass er außerhalb einer Arbeitswarteschlange (z. B.
LinkedBlockingQueue
) ausgeführt wird, anstatt den Thread neu zu starten.quelle
Nein , wir können Thread nicht erneut starten. Dadurch wird die runtimeException java.lang.IllegalThreadStateException ausgelöst. >
Nehmen wir ein Beispiel: Wenn wir daran denken, den Thread erneut zu starten und die start () -Methode darauf aufzurufen (die intern die run () -Methode aufruft), ist dies so etwas wie die Aufforderung an den Toten, aufzuwachen und auszuführen. Als nach Beendigung seines Lebens geht die Person in den toten Zustand.
Überprüfen Sie dies
quelle
Sie sollten eine ausführbare Datei erstellen und sie jedes Mal, wenn Sie die ausführbare Datei ausführen möchten, mit einem neuen Thread versehen. Es wäre wirklich hässlich, dies zu tun, aber Sie können einen Thread mit einem anderen Thread umbrechen, um den Code erneut auszuführen, aber nur dies müssen Sie wirklich tun.
quelle
Wie Sie sagten, kann ein Thread nicht mehr als einmal gestartet werden.
Direkt aus dem Maul des Pferdes: Java API Spec
Wenn Sie erneut ausführen müssen, was in Ihrem Thread vor sich geht, müssen Sie einen neuen Thread erstellen und diesen ausführen.
quelle
Die Wiederverwendung eines Threads ist eine unzulässige Aktion in der Java-API. Sie können es jedoch in eine ausführbare Implementierung einbinden und diese Instanz erneut ausführen.
quelle
Ja, wir können den Thread nicht bereits ausführen. Es wird zur Laufzeit eine IllegalThreadStateException auslösen - wenn der Thread bereits gestartet wurde.
Was ist, wenn Sie den Thread wirklich starten müssen: Option 1) Wenn ein Thread mehr als einmal ausgeführt werden muss, sollte eine neue Instanz des Threads erstellt und start darauf aufgerufen werden.
quelle
Ja. Sie können es genau einmal starten.
Lass das nicht noch
Thread
einmal laufen . Erstellen Sie stattdessen Runnable und veröffentlichen Sie es auf Handler of HandlerThread . Sie können mehrereRunnable
Objekte einreichen . Wenn Sie wollen , Daten zurück zu UI - Thread zu schicken, mit in IhreRunnable
run()
Methode, PostenMessage
aufHandler
der UI - Thread und ProzesshandleMessage
In diesem Beitrag finden Sie Beispielcode:
Android: Toast in einem Thread
quelle
Ich weiß nicht, ob es eine gute Praxis ist, aber wenn ich run () innerhalb der run () -Methode aufrufen lasse, wird kein Fehler ausgegeben und es wird genau das getan, was ich wollte.
Ich weiß, dass es keinen Thread erneut startet, aber vielleicht ist dies für Sie nützlich.
Hoffe das hilft, auch wenn es nur ein bisschen ist.
Prost
quelle
Ich musste ein Ressourcenleck beheben, das von einem Programmierer verursacht wurde, der einen Thread erstellt hat, aber anstatt ihn zu starten (), rief er die run () - Methode direkt auf. Vermeiden Sie es also, es sei denn, Sie wissen wirklich, welche Nebenwirkungen es verursacht.
quelle
run()
direkt aufzurufen , sondern nur ein Runnable in einen Thread einzubetten und vermutlich aufzurufenstart()
.