Frage

Wie töten Sie einen java.lang.Thread in Java?

War es hilfreich?

Lösung

Sehen Sie diesen Thread von Sun auf, warum sie als veraltet Thread.stop() . Es geht ins Detail, warum war dies eine schlechte Methode und was sollte sicher getan werden, um Fäden in der Regel zu stoppen.

Die Art, wie sie empfehlen ist es, eine gemeinsame Variable als Flag zu verwenden, die den Hintergrund-Thread fragt zu stoppen. Diese Variable kann dann von einem anderen Objekt eingestellt werden anfordernden der Thread zu beenden.

Andere Tipps

Im Allgemeinen Sie dies nicht tun ..

Sie bitten, es zu unterbrechen, was es verwendet tun? Thread.interrupt () (javadoc Link)

Eine gute Erklärung, warum in der javadoc ist hier (java technote Link)

In Java-Threads werden nicht getötet, aber das Stoppen eines Threads in einer kooperativen Art und Weise getan . Der Faden wird gebeten, zu beenden, und der Faden kann dann Abschaltung anmutig.

Oft wird ein volatile boolean Feld wird verwendet, die das Gewinde in regelmäßigen Abständen überprüft, und endet, wenn es auf den entsprechenden Wert gesetzt wird.

I nicht verwenden, um eine boolean zu prüfen, ob der Thread sollte beenden . Wenn Sie volatile als Feld Modifikator verwenden, wird dies zuverlässig funktioniert, aber wenn Ihr Code immer komplexer wird, für stattdessen andere Blockierungsmethoden innerhalb der while Schleife verwendet, kann es vorkommen, dass Ihr Code nicht beenden überhaupt nicht oder zumindest dauert länger , wie Sie möchten.

  

Bestimmte Sperr Bibliothek Methoden Unterstützung Unterbrechung.

Jeder Thread hat bereits einen boolean-Flag unterbrochenen Status und Sie sollten davon Gebrauch machen. Es kann wie folgt ausgeführt werden:

public void run() {
   try {
      while (!interrupted()) {
         // ...
      }
   } catch (InterruptedException consumed)
      /* Allow thread to exit */
   }
}

public void cancel() { interrupt(); }

Der Quellcode angepasst von Java Concurrency in Practice . Da die cancel() Methode public ist, können Sie ein anderes Thread lassen diese Methode aufrufen, wie man wollte.

Eine Möglichkeit ist durch eine Klassenvariable Einstellung und als Sentinel verwendet wird.

Class Outer {
    public static volatile flag = true;

    Outer() {
        new Test().start();
    }
    class Test extends Thread {

        public void run() {
            while (Outer.flag) {
                //do stuff here
            }
        }
    }

}

Stellen Sie eine externe Klassenvariable, das heißt flag = true in dem obigen Beispiel. Setzen Sie sich auf false zu ‚töten‘ den Faden.

Es gibt einen Weg, wie Sie es tun können. Aber wenn man es benutzt hatte, entweder sind Sie ein schlechter Programmierer oder Sie verwenden einen Code durch schlechte Programmierer geschrieben. Also, sollten Sie darüber nachdenken, ist ein schlechter Programmierer Anhalten oder Stoppen dieser schlechten Code. Diese Lösung ist nur für Situationen, in denen es keinen anderen Weg.

Thread f = <A thread to be stopped>
Method m = Thread.class.getDeclaredMethod( "stop0" , new Class[]{Object.class} );
m.setAccessible( true );
m.invoke( f , new ThreadDeath() );

Ich möchte einige Bemerkungen hinzufügen, basierend auf den Kommentaren, die angesammelt haben.

  1. Thread.stop () erzeugt einen Thread beenden, wenn der Sicherheitsmanager es erlaubt.
  2. Thread.stop () ist gefährlich. wenn Sie in einer JEE Umgebung Having said that, arbeiten und Sie haben keine Kontrolle über den Code aufgerufen wird, kann es notwendig sein.
  3. Sie sollten niemals einen Container Worker-Thread stoppen stoppen. Wenn Sie Code ausführen wollen, die hängen neigt (vorsichtig) einen neuen Dämon-Thread starten und überwachen es, zu töten, falls erforderlich.
  4. stop () erzeugt einen neuen Threadfehler auf dem Aufruf Thread und dann bewirkt, dass Fehler in dem target Thread angewandt werden. Daher ist der Stack-Trace der Regel wertlos.
  5. In JRE 6 () überprüft, mit dem Sicherheitsmanager stoppen und ruft dann stop1 (), die Anrufe stop0 (). stop0 () ist nativen Code.

ich für Thread.stop() stimmen würde.

Wie zum Beispiel haben Sie einen langlebigen Betrieb (wie ein Netzwerk Anfrage). Angeblich soll warten Sie auf eine Antwort, aber es kann auch auf andere UI navigiert Zeit und den Benutzer nehmen. Dieses Warten Thread ist jetzt a) nutzlos b) potenzielles Problem, denn wenn er Ergebnis erhalten wird, ist es völlig nutzlos ist und er löst Rückrufe, die Anzahl von Fehlern führen kann.

All das, und er kann Antwortverarbeitung tun, die CPU intensiv sein könnte. Und Sie, als Entwickler, kann es nicht einmal stoppen, weil Sie nicht if (Thread.currentThread().isInterrupted()) Linien in allen Code werfen kann.

So ist die Unfähigkeit, mit Gewalt einen Thread es seltsam zu stoppen.

Die Frage ist eher vage. Wenn Sie bedeuten „wie kann ich ein Programm schreiben, so dass ein Thread läuft nicht mehr, wenn ich es will“, dann verschiedene andere Reaktionen hilfreich sein sollten. Aber wenn Sie gemeint: „Ich habe einen Notfall mit einem Server kann ich jetzt nicht neu starten, und ich brauche nur einen bestimmten Thread zu sterben, was kommen kann“, dann müssen Sie ein Interventionswerkzeug Monitoring-Tools wie jstack entsprechen.

Zu diesem Zweck habe ich jkillthread . Siehe seine Anweisungen für die Verwendung.

Es ist natürlich der Fall, wenn Sie irgendeine Art von nicht-ganz-vertrauenswürdigem Code ausgeführt werden. (Ich habe dies persönlich, indem sie hochgeladen Skripte in meiner Java-Umgebung auszuführen. Ja, es gibt Sicherheitsalarmglocke überall klingeln, aber es ist Teil der Anwendung.) In diesem unglücklichen Fall Sie zunächst einmal lediglich hoffnungsvoll zu sein von Drehbuchschreibern zu fragen eine Art von boolean run / Einmalige laufen Signal zu respektieren. Ihre einzige anständige nicht sicher ist, die Stop-Methode auf den Faden zu nennen, wenn, sagen wir, es läuft länger als einige Timeout.

Aber das ist nur „anständig“, und nicht absolut, da der Code des Thread Fehler fangen kann (oder was auch immer Ausnahme werfen Sie explizit), und es nicht erneut auslösen wie ein vornehmer Thread tun soll. So ist die untere Linie AFAIA gibt es keine absoluten ausfallsicher.

Es gibt keinen Weg, um anmutig einen Thread zu töten.

Sie können versuchen, den Faden zu unterbrechen, ist eine commons Strategie eine Giftpille Nachricht zu verwenden, um den Faden selbst zu stoppen

public class CancelSupport {
    public static class CommandExecutor implements Runnable {
            private BlockingQueue<String> queue;
            public static final String POISON_PILL  = “stopnow”;
            public CommandExecutor(BlockingQueue<String> queue) {
                    this.queue=queue;
            }
            @Override
            public void run() {
                    boolean stop=false;
                    while(!stop) {
                            try {
                                    String command=queue.take();
                                    if(POISON_PILL.equals(command)) {
                                            stop=true;
                                    } else {
                                            // do command
                                            System.out.println(command);
                                    }
                            } catch (InterruptedException e) {
                                    stop=true;
                            }
                    }
                    System.out.println(“Stopping execution”);
            }

    }

}

BlockingQueue<String> queue=new LinkedBlockingQueue<String>();
Thread t=new Thread(new CommandExecutor(queue));
queue.put(“hello”);
queue.put(“world”);
t.start();
Thread.sleep(1000);
queue.put(“stopnow”);

http://anandsekar.github.io/cancel-support-for-threads /

Im Allgemeinen Sie nicht töten, zu stoppen, oder einen Thread unterbrechen (oder überprüfen wheter es unterbrochen wird ()), aber lassen Sie es natürlich beenden.

Es ist einfach. Sie können jede Schleife verwenden, zusammen mit (volatile) Boolesche Variable innerhalb run () Methode Thread-Aktivität zu steuern. Sie können auch aus dem aktiven Thread zu dem Haupt-Thread zurückkehren, ihn zu stoppen.

Auf diese Weise können anmutig einen Thread :) töten.

Versuche von abrupter Faden Beendigung sind bekannte schlechte Programmierpraxis und Beweise für schlechtes Anwendungsdesign. Alle Fäden in der Multi-Thread-Anwendung explizit und implizit den gleichen Prozesszustand teilen und gezwungen, miteinander zusammenzuarbeiten, um es konsistent zu halten, sonst wird Ihre Anwendung auf die Fehler anfällig sein wird, die wirklich schwer zu diagnostizieren. Also, es ist eine Verantwortung der Entwickler eine Zusicherung einer solchen Konsistenz über eine sorgfältige und klare Anwendungsdesign zur Verfügung zu stellen.

Es gibt zwei Haupt richtigen Lösungen für die gesteuerten Fäden Abschlüsse:

  • Die Verwendung des gemeinsamen flüchtigen Flag
  • Verwendung des Paares von Thread.interrupt () und Thread.interrupted () -Methoden.

Gute und detaillierte Erklärung der auf die abrupten Fäden Beendigung Fragen sowie Beispiele von falschen und richtigen Lösungen für die kontrollierten Faden Terminierung kann hier gefunden werden:

https://www.securecoding.cert.org/confluence/display/java/THI05-J.+Do+not+use+Thread.stop%28%29+to+terminate+threads

‚einen Thread zu töten‘ ist nicht der richtige Ausdruck zu verwenden. Hier ist ein Weg, wir anmutige Abschluss / Ausfahrt des Fadens auf Willen umsetzen können:

Runnable, die ich verwendet:

class TaskThread implements Runnable {

    boolean shouldStop;

    public TaskThread(boolean shouldStop) {
        this.shouldStop = shouldStop;
    }

    @Override
    public void run() {

        System.out.println("Thread has started");

        while (!shouldStop) {
            // do something
        }

        System.out.println("Thread has ended");

    }

    public void stop() {
        shouldStop = true;
    }

}

Die Auslöseklasse:

public class ThreadStop {

    public static void main(String[] args) {

        System.out.println("Start");

        // Start the thread
        TaskThread task = new TaskThread(false);
        Thread t = new Thread(task);
        t.start();

        // Stop the thread
        task.stop();

        System.out.println("End");

    }

}

Ich habe nicht den Interrupt bekommen in Android zu arbeiten, so habe ich diese Methode funktioniert perfekt:

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;
 }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top