Wie stoppe ich einen Thread richtig?

Status
Nicht offen für weitere Antworten.

JBubble

Mitglied
Hallo zusammen,

ich habe in einer Anwendung einen Thread, der folgendermaßen gestartet wurde:

Code:
Thread t = new Thread(xxx);
t.start();

Bei xxx handelt es sich um ein Objekt, welches eine Schnittstelle implementiert, die direkt von Runnable erbt. So weit so gut. Doch wie stoppe ich einen solchen Thread wieder sauber?

Gemäß http://java.sun.com/j2se/1.3/docs/guide/misc/threadPrimitiveDeprecation.html kann

Code:
t.stop();

zu inkonsistenten Daten führen. Sie empfehlen daher, in der run()-Methode des Threads permanent eine Variable zu überpüfen, die in der stop()-Methode verändert werden kann. Dies kann dann quasi so aussehen:

Code:
private volatile boolean running = true;
public void stop() {
running = false;
}

public void run() {
while(running) {
...
}
}

Zumindest verstehe ich das Beispiel so ähnlich. Nun gelingt es mir leider nicht, dieses saubere Beenden auf meine Implementierung oben anzuwenden. Wo genau sollte ich denn jetzt diese stop()-Methode implementieren? In der Klasse von xxx (siehe Beispiel oben, ist quasi ein Runnable) macht es ja keinen Sinn, denn ich würde später ja doch wieder die Methode stop() des Objekts t aufrufen - oder doch direkt von xxx, so dass ich quasi sage

Code:
// Thread t stoppen:
xxx.stop();

Würde dies den Thread t sauber beenden, oder gibts da was anderes?

Wenn ich direkt von Thread ableite kann ich stop() nicht überschreiben, da dies eine final-Methode ist.

Bin für jede Anregung und jeden Denkanstoß dankbar,
viele Grüsse
JBubble
 

Reality

Top Contributor
Die stop-Methode sollst du überhaupt nicht verwenden. Der Code mit der boolean-Variable ist schon richtig. Wenn du den Thread stoppen willst, setzt du ihn auf false.

Liebe Grüße
Reality
 

foobar

Top Contributor
Am besten verwendest du isInterrupted:
Code:
public void run()
{
    while (! isInterrrupted())
     {
        System.out.println("running");
     }
}

Thread stoppen:
Code:
myThread.interrupt();
 
M

mr1st

Gast
Was ist aber, wenn ein Thread nur einen Befehl, zB ein großes Bild laden, durchzuführen hat. Wie kann man denn das sauber abbrechen?
 

Icewind

Bekanntes Mitglied
hm dann musst du immer wieder wärend dem laden überpfüfen ob interrupted worden ist und wenn ja den thread abbrechen.....

hm naja im oben genannten beispiel kann man nicht mehr abbrechen...

aber mit isInterrupted() wird glaub ich das interruptet flag wieder zurückgesetzt.... also kann man "weitermachen"
 

JBubble

Mitglied
Hallo und erstmal danke für eure Antworten.

@Reality: Mir ist halt nicht ganz klar wo ich die Variable setzen und wo modifzieren muss, wenn ich den Thread über ein Runnable-Objekt instantiiere. Muss das im Runnable-Objekt selbst geschehen (bspw. in seiner stop()-Methode). Muss ich dann die stop()-Methode des Runnable-Objekts aufrufen statt die des 'eigentlichen' Thread?

@foobar: interrupt() sollte die Aufgabe soweit erfüllen. In meinem Fall ist es nicht notwendig, einen einmal unterbrochenen Thread wieder fortzusetzen, von daher werd ich mich wohl für diese Lösung entscheiden. Wichtig ist mir einfach nur, dass der Thread sauber und ohne die Möglichkeit, inkonsistente Daten zu haben, beendet wird. Wenn interrupt() das macht, ist es genau das Richtige.

Danke nochmal und noch nen schönen Abend,
viele Grüsse JBubble
 

Icewind

Bekanntes Mitglied
aja zu interrupt sein noch anzumerken das er wenn der thread zb in einem sleep ist, eine interrupted exception geworfen wir....
 

thE_29

Top Contributor
warum soll man eigentlich einen thread net mit stop stoppen?
der befehl hätte ja den richtigen namen dazu ;)
 

dotlens

Top Contributor
weil er ihn abwürgt und das kann zu inkonsistenten Daten führen. bei interrupt bittet man den Thread nur aufzuhüren, also kann er seine aktion zuerst noch beenden...
 

thE_29

Top Contributor
aso, und wenn ich es so mache

Code:
new Thread(new Thread(){
public void run(){
//funktionen
.....
stop(); //hier ist es einfach aus
}}).start();
hier würge ich ihn ja nicht ab, oder brauche ich hier gar kein stop(); ?
 

dotlens

Top Contributor
hbrauchst du kein stop, da sich der thrasd selbst beendet wenn alle funktionen durchlaufen sind. man benötigt es eigentlich nur, wenn der Thread eine while schleife enthält.
 

Bleiglanz

Gesperrter Benutzer
Eigentlich soll man einen Thread gar nicht "stoppen" bzw. "abwürgen"!

Lass ihn auf eine gemeinsame threadsichere Ressource zugreifen, die ein Flag enthält, das ihm sagt, ob er noch weiterlaufen soll (also im obigen Beispiel etwa "running", nur mit der Möglichkeit, "running" von aussen zu manipulieren)
 
G

Gast

Gast
Um das Thema eindeutig zu klären, wäre ein Beispielcode, der
aufzeigt, wie man einen Thread stoppt und selbigen fortsetzt
sehr interessant.
 

dotlens

Top Contributor
für dich mach ich doch alles ;):

Code:
class ThreadusInterruptus extends Thread {

	public void run() {
		System.out.println("Der Anfang");

		while (true) {
			if(isInterrupted())
				break;

			System.out.println("Hurra");

			try {
				Thread.sleep(500);
			}
			catch (InterruptedException e) {
				interrupt();
			}
		}

		System.out.println("Das Ende");
	}

	public static void main(String args[]) {
		ThreadusInterruptus t = new ThreadusInterruptus();

		t.start();

		try {
			Thread.sleep(2000);
		}
		catch (InterruptedException e) {}

		t.interrupt();
	}
}

kommentar:
"Das Ende" wird ausgegeben, was heisst, dass der Thread nicht abgewürgt wurde, sonder höflich gebittet wurde und seine Angelegenheite benden konnte
 

Illuvatar

Top Contributor
Jetzt wollte ich gerade ein Beispiel schreiben, dass zeigt, dass Thread#stop schlecht ist, weil noch locks bestehen könnten, merke aber dank dem Beispiel, dass die Methode die locks wieder freigibt ;)
 

JBubble

Mitglied
Also ich möchte jetzt doch noch mal genauer nachfragen, weil ich entweder total auf dem Schlauch stehe oder einfach zu wenig Erfahrung mit solchen Dingen habe:

Vom Prinzip her ist mir das Beenden vollkommen klar: Eine gemeinsame Ressource (bspw. eine Variable running) wird irgendwann auf false gesetzt, und der Thread beendet sich. Wenn ich eine Klasse hab, die von Thread erbt, ist das auch alles kein Problem, aber wie mache ich das mit einer Klasse, die Runnable implementiert? Ich schreibe hier mal ein konkretes Beispiel auf und würd mich freuen wenn mir jemand den entscheidenden Hinweis gibt:

Das Runnable-Objekt:
Code:
public class MyThread implements Runnable {

  public void run() {
    for(int i=0; i<10; i++) {
      System.out.println(i);
        try {
          Thread.sleep(1000);
        }
        catch(Exception ex) {}
    }
  }
}

Der Code aus dem es aufgerufen wird:
Code:
class IrgendWas {
  Thread t;

  public void startThread() {
    // hier wird der Thread gestartet
    t = new Thread(new MyThread());
    t.start();
  }

  public void stopThread() {
    // und hier soll der Thread gestoppt werden --> nur wie?
  }
}

Ich kann in stopThread() ja nicht t.stop() aufrufen, und eine direkte Referenz auf das Runnable-Objekt hab ich auch nicht. Klar, wär kein Problem das umzuschreiben - müsste ich dann die stop()-Methode des Runnable-Objekts aufrufen und darin die Variable running auf false setzen?

Nochmal herzlichen Dank für eure Hilfe,
viele Grüsse
JBubble
 

meez

Top Contributor
Code:
public class MyThread implements Runnable {

  public void run() {
   while (! Thread.currentThread().isInterrupted()) {
    for(int i=0; i<10; i++) {
      System.out.println(i);
        try {
          Thread.sleep(1000);
        }
        catch(Exception ex) {}
    }
  }
  Thread.currentThread().interrupt();
 }
}

this... Würde wohl auch gehen anstatt currentThread


Code:
class IrgendWas {
  Thread t;

  public void startThread() {
    // hier wird der Thread gestartet
    t = new Thread(new MyThread());
    t.start();
  }

  public void stopThread() {
    t.interrupt();
  }
}
 

JBubble

Mitglied
Tut mir leid, aber der Code funktioniert nicht wie erwartet.

In diesem Fall würde die for-Schleife ja auch zu Ende laufen, wenn der Thread unterbrochen wurde. Ich möchte allerdings, dass die for-Schleife unterbrochen wird.

Auch ein Konstrukt wie

Code:
for(int i=0; i<10; i++) {
  if(Thread.currentThread().isInterrupted()) {
    break;
  }
  // usw.
}

hält den Thread einfach nach einem t.interrupt() nicht an. Oben hat mal einer geschrieben dass eine Exception geworfen wird falls der Thread gerade schläft (was dieser ja fast ausschließlich tut), doch selbst wenn ich einen try-catch-Block um das t.interrupt() baue fange ich keine Exception.
Btw., wenn ich deine Lösung nehme hört der Thread nie mehr auf zu laufen ... irgendwie haut das mit interrupt() nicht hin. Wo könnte der Fehler liegen?
this darf ich statt currentThread() übrigens nicht nehmen, da das Objekt selbst (MyThread) keine isInterrupted()-Methode kennt. Runnable verlangt nur eine run()-Methode.
Achja, falls es was hilft, ich verwende das JDK 1.4.2_04 von Sun.

Viele Grüsse,
JBubble
 

Reality

Top Contributor
JBubble hat gesagt.:
@Reality: Mir ist halt nicht ganz klar wo ich die Variable setzen und wo modifzieren muss, wenn ich den Thread über ein Runnable-Objekt instantiiere. Muss das im Runnable-Objekt selbst geschehen (bspw. in seiner stop()-Methode). Muss ich dann die stop()-Methode des Runnable-Objekts aufrufen statt die des 'eigentlichen' Thread?
Die boolean-Variable ist global, sonst kannst du ja von außen nicht zugreifen und die Variable auf false setzen, damit die Schleife aufhört.
Und die stop-Methode wird NICHT benutzt, sondern NUR die boolean-Variable auf false gesetzt und schon hört die Schleife in dem Thread auf. Wenn du den Thread fortführen willst, setzt du sie wieder auf true.

Liebe Grüße
Reality
 

JBubble

Mitglied
Danke Reality, so scheint das erstmal zu laufen :).

Würde mich trotzdem mal interessieren warum das mit interrupt() nicht funktioniert hat.

Wünsch euch noch nen schönen Abend,
viele Grüsse
JBubble
 
L

Leseratte

Gast
Code:
public class myThread
extends AnyClass      //kann natürlich auch "Thread" sein. Allerdings braucht man dann 
implements Runnable   //Runnable nicht mehr!
{
    private boolean stopped = false; //aus Synchronisationsgründen "private"
    private boolean paused = false;  //aus Synchronisationsgründen "private"
    private Thread t;                //aus Sicherheitsgründen "private"

    public void run()
    {
        while (!stopped) {
            //Running Code...
            //stopped und paused können immer wieder abgefragt werden
            while (!paused) {
                //Noch mehr Running Code...
                //stopped und paused können selbstverständlich auch hier abgefragt werden
            }
        }
        t.interrupt();
        t = null; //forcing Thread to be KILLED! Nicht wirklich wichtig;
    }

    public synchronized boolean isStopped()
    {
        return stopped; //Durch diese Methode lässt sich von paused von Aussen
                        //abfragen. Durch synchronized wird das 'ne ganz
                        //saubere Sache.
    }

    public synchronized boolean isPaused()
    {
        return paused; //Siehe oben
    }

    public synchronized void Stop() // Beachten Sie!!! die Schreibweise von "Stop"!!!
    {
        stopped = false;
        paused = true; //Sonst bleibt der Thread möglicherweise in einer durch paused
                       //angehaltenen Schleife stehen.
    }

    public synchronized void Start()
    {
        if (stopped && t.isInterrupted()) { //Wenn das immer false ergibt,
                                            //"t.isInterrupted()" durch "t == null"
                                            //ersetzen. Nun ist der Thread-Killer
                                            //in run() NOTWENDIG! (Doch wirklich wichtig)
            t = new Thread(this);
            t.start();
            stopped = false; //mit "stopped = paused = false;" würden beide Variablen
                             //auf ein Object instanziert. Die Änderung eines Wertes
            paused = false;  //wirkt sich dann auch auf den anderen aus.
        }
    }

    public synchronized void Pause()
    {
        paused != paused; // oder paused = !paused;
    }
}
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
smarterToby Wie stoppe ich diesen Thread Allgemeine Java-Themen 4
Jose05 Umgang mit Exceptions in einen Programm Allgemeine Java-Themen 2
Robert Zenz Ich brauche bitte mal kurz einen Sanity/Reality-Check betreffend Tests. Allgemeine Java-Themen 9
R Wie gestaltet man einen Authentifizierungsflow? Allgemeine Java-Themen 6
berserkerdq2 Jemand einen Tipp wie man ein Javafx-Hintergrund "dynamisch" macht Allgemeine Java-Themen 3
berserkerdq2 Text über einen Shape anzeigen (Scenebuilder) Allgemeine Java-Themen 1
Lennox Schinkel Java Kara Auf einen Java Host laufen lassen Allgemeine Java-Themen 17
A verschachtelte for-Schleife in einen Stream umwandeln? Allgemeine Java-Themen 4
N Wie mache ich einen UnitTest? Allgemeine Java-Themen 16
D Klassendesign für einen Pascal Interpreter Allgemeine Java-Themen 6
Jose05 Gibt es einen Nachteil bei dem JDK 8? Allgemeine Java-Themen 7
E Objekte in einen String packen und wieder laden Allgemeine Java-Themen 5
O Warum kann ich so keine Elemente löschen und erhalte einen IllegalStateException? Allgemeine Java-Themen 4
M Schleife für einen TicTacToe Computer Allgemeine Java-Themen 5
N Validator für einen SQL-Befehl Allgemeine Java-Themen 22
ZH1896ZH Best Practice Wie erstellt man am besten einen Kalender? Allgemeine Java-Themen 3
R Java Stream: Ist es möglich, einen stream zusammenzufassen Allgemeine Java-Themen 6
Zrebna FileUtils.cleanDirectory() - aber einen sub-Ordner "verschonen" Allgemeine Java-Themen 1
MiMa Datei verschieben hat einen Fehler?? Allgemeine Java-Themen 20
L Generator für einen Parser implementieren Allgemeine Java-Themen 13
W Haben Konstruktoren in Java eigentlich immer mindestens einen Parameter? Allgemeine Java-Themen 4
J Wie kann ich von Vornherrein einen Fokus auf ein Objekt entfernen? Allgemeine Java-Themen 3
P einen public <Optinal String> in einer anderen Klasse mit einem Int vergleichen Allgemeine Java-Themen 2
A Mithilfe von einer Nummer einen Namen finden n-Beziehung Allgemeine Java-Themen 8
B Long in einen Double umwandeln und im Label anzeigen Allgemeine Java-Themen 7
E Hat der Compiler einen Fehler oder warumbeendet return nicht eine Methode ? Allgemeine Java-Themen 7
MoxxiManagarm Ich brauche einen smarten Ansatz Allgemeine Java-Themen 23
J Gebautes Jar per Maven in einen Docker Container kopieren Allgemeine Java-Themen 0
Drachenbauer Wie kann eine vorgegebene Farbe über einen String erkannt werden? Allgemeine Java-Themen 11
L File beim Kopieren in einen anderen Ordner umbenennen Allgemeine Java-Themen 6
E Einen Bot Programmieren. Allgemeine Java-Themen 6
F Operationen/Methoden einen WebService im Browser mit Apache Axis aufrufen Allgemeine Java-Themen 4
N Über einen Button in JavaFX ein Event über eine Pipeline schicken(Netty) Allgemeine Java-Themen 1
J Einen Thread in einer Schleife Allgemeine Java-Themen 2
P [Webdriver] einen Datensatz signieren Allgemeine Java-Themen 0
R MAC-Adresse eindeutig für einen PC ? Bezug zu Netzwerk, wieso ? Allgemeine Java-Themen 7
L Variablen Eigenes Objekt wie z.B. einen Integer zuweisen Allgemeine Java-Themen 3
N Wie öffne ich einen runtergeladadenen Code in IntelliJ Allgemeine Java-Themen 3
R Wie einen ClientBuilder / JarBuilder programmieren? Allgemeine Java-Themen 14
S Input/Output Beste Möglichkeit einen String in einen Datei zu Schreiben Allgemeine Java-Themen 2
L Input/Output Wie kann man in der Konsole einen Text farbig ausgeben z.b in grün Allgemeine Java-Themen 6
L Wie programmiert man einen Listener? Allgemeine Java-Themen 1
M Nanosekunden-Pause innerhalb einen Thread-Loops Allgemeine Java-Themen 3
Thallius Wie convertiere ich einen pkcs8 key in einen java lesbaren? Allgemeine Java-Themen 16
M Was braucht man, um einen Java Job zu bekommen? Allgemeine Java-Themen 8
G Substrings in einen String zusammenfassen Allgemeine Java-Themen 5
C Classpath Neue Klasse über einen Button ausführen Allgemeine Java-Themen 3
N Compiler-Fehler Warum erhalte ich einen Nullpointer Fehler? Allgemeine Java-Themen 2
P Zum src Ordner einen Projektes navigieren Allgemeine Java-Themen 8
J Abhängigkeit zwischen Rechenzeit und Speicherbedarf in einen Algorithmus Allgemeine Java-Themen 7
MaxG. Swing Wie kann man einen Dateiordner auswählen ? Allgemeine Java-Themen 3
D Kopieren von Dateien aus einem Ordner in einen anderen Allgemeine Java-Themen 6
KeVoZ_ int Werte in einen String fassen Allgemeine Java-Themen 4
RalleYTN Problem bei Schleife die durch einen 2D raum iterieren soll Allgemeine Java-Themen 1
S Einen Punkt um den Ursprung drehen Allgemeine Java-Themen 5
Tausendsassa Threads Einen Thread sich selbst schließen lassen Allgemeine Java-Themen 17
M Genaues Bugtracking - jemand einen Vorschlag? Allgemeine Java-Themen 14
L Gibt es in Java einen Property Editor? Allgemeine Java-Themen 2
S Einen übergebenen String kopieren Allgemeine Java-Themen 3
J Wie erschaffe ich einen sicheren Datenaustausch zwischen Thread und Nicht-Threads Allgemeine Java-Themen 8
L Wie kann ich einen Keystore aus existierenden Zertifikaten erstellen? Allgemeine Java-Themen 1
P Vectorelemente in einen anderen Vector kopieren Allgemeine Java-Themen 12
U in java an einen Rückgabewert aus matlab rankommen Allgemeine Java-Themen 2
B einen color-chooser bauen, ähnliche Farben vermeiden Allgemeine Java-Themen 5
B .txt Datei in einen kompletten String konvertieren Allgemeine Java-Themen 20
H Gibt es einen großen Unterschied zwischen Java 6 und Java 7? Allgemeine Java-Themen 3
M String in einen 2D array bringen Allgemeine Java-Themen 2
Y Prüfen ob ein Graph immer einen von mehren Enden erreicht Allgemeine Java-Themen 4
J (Java3D) Einen Faden programmieren - Logikproblem Allgemeine Java-Themen 5
Y Applet/Html - Wie Java-Methode aufrufen, die einen Parameter erwartet? Allgemeine Java-Themen 3
Rudolf In wie fern lohnt sich C++ für einen Javaentwickler Allgemeine Java-Themen 70
A Welches Speichermanagement für einen Kalkulator Allgemeine Java-Themen 7
S OOP Objekte als Return-Werte: Einen Klon zurückgeben oder Instanz auf das Feld? Allgemeine Java-Themen 10
J String-Typ in einen generischen Typ T umwandeln Allgemeine Java-Themen 6
S RandomAcessFile das einen InputStream wrappt..? Allgemeine Java-Themen 2
H Scanner soll einen Inputredirect einlesen, liest aber nicht jedes Wort ein. Allgemeine Java-Themen 3
H Wie erzeugt man einen Daemon? Allgemeine Java-Themen 7
S Wie beendet man einen Process in Java Platform unabhänging? Allgemeine Java-Themen 8
Z Threads Thread für einen Client Allgemeine Java-Themen 9
A nur einen Wert aus einer .conf lesen und erneuern Allgemeine Java-Themen 3
S MANIFEST DATEI hat nur einen Eintrag Allgemeine Java-Themen 14
M Einen Prozess "crashen" lassen Allgemeine Java-Themen 9
I getResponseCode(); returnt einen falschen Wert? Allgemeine Java-Themen 7
U Wie kann mit einen Java Applet Dateien erstellen,verschieben und löschen? Allgemeine Java-Themen 9
C Argument an einen Thread übergeben Allgemeine Java-Themen 4
A Framework für einen Web Service Allgemeine Java-Themen 6
I %AppData% Variable für einen Prozess setzen Allgemeine Java-Themen 23
V Gibt es einen Variablen Cast? Allgemeine Java-Themen 8
S regex für einen Link Allgemeine Java-Themen 3
M Client für einen Webservice erstellen (ONVIF) Allgemeine Java-Themen 3
T Undwandlung eines String in einen InputStream? Allgemeine Java-Themen 3
M Selbst geschriebener InputStreamReader über einen beliebigen InputStream Allgemeine Java-Themen 4
P Datei in einen String lesen Probleme bei Codierung Allgemeine Java-Themen 2
H SwingWorker statt Thread für einen Server Allgemeine Java-Themen 2
G einen Thread beim Schlafen überraschen und abschießen Allgemeine Java-Themen 3
A Variable Parameterinhalte an einen Query übergeben? Allgemeine Java-Themen 3
M einen Tag addieren Allgemeine Java-Themen 11
T In der JVM einen weiteren, unabhängigen Prozess starten Allgemeine Java-Themen 11
Schandro Datei öffnen mit... Bestimmten Dateityp mit einen Java-Programm öffnen lassen Allgemeine Java-Themen 5
B Gibt es einen Unterschied zwischen Java 1.2 und Java 2? Allgemeine Java-Themen 7

Ähnliche Java Themen

Neue Themen


Oben