Interrupt / Kill einen laufenden Thread

9

Beim Auftreten eines bestimmten Timeouts muss ich einen laufenden Thread beenden / abbrechen / unterbrechen / fehlschlagen. Ich benutze ExecutorService, um einen Pool von Threads zu verwalten, durch den ich die Aufgabe mithilfe der cancel () -Methode von Future abbrechen kann, die dies aus der Ansicht des ExecutorService entfernt, aber der Thread selbst läuft weiter.

Wenn Sie sich online umsehen, sprechen Sie über das Unterbrechen von Threads , die eine Schleife mit der isInterrupted () -Methode oder warten auf IO, die durch das Auftauchen von InterruptedException behandelt werden kann.

Was ist die allgemeine Vorgehensweise beim Töten von Threads, die keine Schleife (oder irgendwelche anderen Hooks) haben und nicht auf IO warten? Sich umschauend, scheint Thread.stop () zu tun, was ich brauche (einfach den Thread blind zu töten), aber es wird nicht empfohlen, verwendet zu werden.

    
nija 23.12.2011, 11:17
quelle

3 Antworten

3

Wenn Sie ExecutorService verwenden, sollten Sie sich nicht mit seinen Threads anlegen: dieser Begriff ist hinter dem Executor verborgen, der eine höhere Ebene als Threads darstellt und daher keine Methoden zu deren Verwaltung bietet. Ich rate Ihnen dringend, den gesamten Executor zu stoppen und nicht einen der Threads zu stoppen.

Bitte beachten Sie, dass die Threads in ExecutorService Schleifen durchlaufen. Ihre Schleife enthält das Warten darauf, dass eine Aufgabe in ihrer Aufgabenwarteschlange verfügbar ist.

Es gibt in Java keinen einfachen Mittelwert, um einen Thread zu stoppen, der keine Schleife ist. Was Sie tun können, ist:

  • Ein flüchtiges boolesches Flag, das die Runnable des Threads überprüft, um zu sehen, ob es anhalten sollte (dasselbe Flag, das als Bedingung in einer Thread-Schleife verwendet werden könnte).
  • Rufen Sie Thread.interrupt() auf, um zu versuchen (am besten, ziemlich unsicher, wenn Sie nicht wissen, was Sie tun), stoppen Sie eine synchronisationsbedingte Wartezeit / lock / aquire / ... der Thread bleibt stecken.
Guillaume 23.12.2011 11:27
quelle
1

Wenn Sie bereits Executorservice haben, dann haben Sie bereits Future erhalten. Der einzige vernünftige und saubere Weg zum Abbrechen des Jobs lautet daher future.cancel(boolean mayInterruptIfRunning) . Wenn Sie mayInterruptIfRunning einstellen, werden die Jobs unterbrochen, wenn sie gerade ausgeführt werden, und nichts, wenn der Job nicht ausgeführt wird. Sie müssen den Job nur so schreiben, dass er die Unterbrechung berücksichtigt, indem Sie ab und zu Thread.interrupted() überprüfen.

Bitte beachten Sie den Unterschied zwischen einem Job und einem Thread . Sie reichen einen Job ein und sollten daher nicht mit einem thread meckern, indem Sie versuchen, die ExecutorService zu umgehen, die überhaupt nicht amüsiert ist. Wenn Sie Future.cancel(true) aufrufen, geben Sie allen Beteiligten ein klares Signal, was zu tun ist.

    
A.H. 23.12.2011 12:07
quelle
1

Ich würde Ihnen persönlich empfehlen, die Unterbrechungsroute zu wählen, da dies der sauberste Weg und der anmutigste Weg ist, diesen Thread zu beenden.

Versuchen wir, unser Ziel klar zu definieren. Ein Thread ist nichts anderes als ein separater Prozess, der eine Reihe von Aufgaben ausführt, denen Sie ihn zuweisen. Wahrscheinlich müssen Sie die unterbrechbaren Punkte in Ihrem Code finden und müssen an diesen Stellen einen unterbrochenen () Check durchführen. Offensichtlich sollten diese Punkte ein logisches Ende erreicht haben.

Zum Beispiel

%Vor%     
bragboy 23.12.2011 11:27
quelle

Tags und Links