Wie tötet man einen java.lang.Thread
in Java?
Antworten
Zu viele Anzeigen?Der Versuch einer abrupten Beendigung von Threads ist eine bekannte schlechte Programmierpraxis und ein Beweis für ein schlechtes Anwendungsdesign. Alle Threads in einer Multithreading-Anwendung teilen sich explizit und implizit denselben Prozessstatus und sind gezwungen, miteinander zu kooperieren, um diesen konsistent zu halten, andernfalls wird Ihre Anwendung anfällig für Fehler, die nur schwer zu diagnostizieren sind. Es liegt also in der Verantwortung des Entwicklers, eine solche Konsistenz durch ein sorgfältiges und klares Anwendungsdesign zu gewährleisten.
Es gibt im Wesentlichen zwei richtige Lösungen für die kontrollierten Fadenabschlüsse:
- Verwendung des Shared Volatile Flag
- Verwendung der beiden Methoden Thread.interrupt() und Thread.interrupted().
Eine gute und ausführliche Erklärung der Probleme im Zusammenhang mit der abrupten Beendigung von Threads sowie Beispiele für falsche und richtige Lösungen für die kontrollierte Beendigung von Threads finden Sie hier:
Hier finden Sie einige gute Informationen zu diesem Thema:
Ich habe die Unterbrechung in Android nicht zum Laufen gebracht, also habe ich diese Methode verwendet, die perfekt funktioniert:
boolean shouldCheckUpdates = true;
private void startupCheckForUpdatesEveryFewSeconds() {
Thread t = new Thread(new CheckUpdates());
t.start();
}
private class CheckUpdates implements Runnable{
public void run() {
while (shouldCheckUpdates){
//Thread sleep 3 seconds
System.out.println("Do your thing here");
}
}
}
public void stop(){
shouldCheckUpdates = false;
}
Thread.stop ist veraltet, wie kann man einen Thread in Java anhalten?
Verwenden Sie immer die Unterbrechungsmethode und die Zukunft, um eine Stornierung zu beantragen.
-
Wenn die Aufgabe auf ein Unterbrechungssignal reagiert, z. B. durch die Methode "Blocking Queue Take".
Callable < String > callable = new Callable < String > () { @Override public String call() throws Exception { String result = ""; try { //assume below take method is blocked as no work is produced. result = queue.take(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } return result; } }; Future future = executor.submit(callable); try { String result = future.get(5, TimeUnit.SECONDS); } catch (TimeoutException e) { logger.error("Thread timedout!"); return ""; } finally { //this will call interrupt on queue which will abort the operation. //if it completes before time out, it has no side effects future.cancel(true); }
-
Wenn die Aufgabe nicht auf das Interrupt-Signal reagiert: Angenommen, die Aufgabe führt Socket-E/A aus, die nicht auf das Interrupt-Signal reagiert, und daher wird die Aufgabe mit dem obigen Ansatz nicht abgebrochen, sondern die Zeit wird abgelaufen sein, aber der Abbruch im Finally-Block hat keine Wirkung, der Thread hört weiter auf den Socket. Wir können den Socket schließen oder die Close-Methode der Verbindung aufrufen, wenn sie vom Pool implementiert wurde.
public interface CustomCallable < T > extends Callable < T > { void cancel(); RunnableFuture < T > newTask(); }
public class CustomExecutorPool extends ThreadPoolExecutor { protected < T > RunnableFuture < T > newTaskFor(Callable < T > callable) { if (callable instanceof CancellableTask) return ((CancellableTask < T > ) callable).newTask(); else return super.newTaskFor(callable); } }
public abstract class UnblockingIOTask < T > implements CustomCallable < T > { public synchronized void cancel() { try { obj.close(); } catch (IOException e) { logger.error("io exception", e); } }
public RunnableFuture < T > newTask() { return new FutureTask < T > (this) { public boolean cancel(boolean mayInterruptIfRunning) { try { this.cancel(); } finally { return super.cancel(mayInterruptIfRunning); } } }; }
}
Nach mehr als 15 Jahren der Entwicklung in Java möchte ich der Welt eines sagen.
Abgelehnt Thread.stop()
und der ganze heilige Kampf gegen seine Verwendung ist nur eine weitere schlechte Angewohnheit oder ein Konstruktionsfehler, der leider Realität geworden ist... (z. B. wollen wir über die Serializable
Schnittstelle?)
Der Kampf konzentriert sich auf die Tatsache, dass das Beenden eines Threads ein Objekt in einen inkonsistenten Zustand versetzen kann. Und nun? Willkommen bei der Multithread-Programmierung. Sie sind ein Programmierer, und Sie müssen wissen, was Sie tun, und ja, das Töten eines Threads kann ein Objekt in einem inkonsistenten Zustand hinterlassen. Wenn Sie sich darüber Sorgen machen, verwenden Sie eine flag
und lassen Sie das Thema in aller Ruhe ruhen; aber es gibt Tausende von Fällen, in denen kein Grund zur Sorge besteht.
Aber nein wenn Sie eingeben thread.stop()
werden Sie wahrscheinlich von allen Leuten, die Ihren Code ansehen/kommentieren/verwenden, getötet werden. Sie müssen also eine flag
anrufen interrupt()
, Ort if(!flag)
um Ihren Code herum, weil Sie überhaupt keine Schleifen machen, und schließlich beten dass die Bibliothek eines Drittanbieters, die Sie für Ihren externen Aufruf verwenden, korrekt geschrieben ist und nicht mit dem InterruptException
unsachgemäß.
- See previous answers
- Weitere Antworten anzeigen