Thread stoppen mit System.in.read()

Gina

Mitglied
Hallo,

ich habe ein Programm geschrieben, dass sich nicht mehr stoppen lässt.

So sieht der Code aus:
Java:
package hiphopSeite244;

import java.util.*;
public class HipHop implements Runnable {

    @Override
    public void run() {
        while(true) {
            String name = Thread.currentThread().getName();
            System.out.println(name);
            Random random = new Random();
            try {
                Thread.sleep(1000 + random.nextInt(2000));
            } catch (InterruptedException e) {
                // TODO: handle exception
            }
        }

    }

    public static void main(String[] args) throws java.io.IOException {
        Thread hip = new Thread(new HipHop());
        Thread hop = new Thread(new HipHop());
        hip.start();
        hop.start();
        System.in.read();
        hip.interrupt();
        hop.interrupt();
        System.out.println("Ende");
        

    }

}

Gedacht hatte ich mir das so, dass die beiden Threads eine zeitlang laufen, und dass der main-Thread solange blockiert bis ich die Enter-Taste drücke. Danach werden die beiden Threads hip und hop unterbrochen und die main-Methode läuft aus. Nur leider funktioniert das Programm nicht so, wie ich mir das überlegt habe und läuft so lange weiter, bis ich Eclipse schließe. Woran könnte es liegen? -Für etwas Unterstützung wäre ich dankbar.

Viele Grüße, Gina
 

Sen-Mithrarin

Gesperrter Benutzer
ich würd mal sagen das liegt daran das es einfach schlecht ... oder ein deinem fall : falsch ... programmiert ist

soweit ich mir deinen code ansehe macht er genau das was er soll ... nämlich zwei threads starten ... auf einen input warten ... die threads interrupten ... und diese schlucken es einfach und laufen weiter ...


guck dir noch mal ganz genau den programm-ablauf an ... es ist relativ einfach ... und lässt sich mit mehr als nur einer lösung "korrekt" stellen
 

anti-held

Bekanntes Mitglied
Wenn du die Methode [c]interrupt()[/c] eines Threads aufrufst, wird einfach eine Interruptedexception bei diesem geworfen.
Diese tritt bei deinem HipHop Thread auf während du wartest (während deinem sleep).
Du fängst diese mit dem try-catch-Block auf und fängst die Schleife erneut von vorne an.

-> Deshalb werden deine Threads auch nicht beendet.
 

Sen-Mithrarin

Gesperrter Benutzer
boa ... gnampf ... kann man nicht einfach mal die fresse halten ... warum müssen es immer alle so direkt raushauen ? ... leute ... das hat nichts mit helfen oder lernen zu tun sondern einfach mit vorgeben von lösungen ...
 

Gina

Mitglied
Hallo!

Danke für die Antworten -nun weiß ich schon mal, wo ich schauen muss. Ich habe versucht, das Problem mit einer break-Anweisung in dem catch-Block zu lösen:
Java:
package hiphopSeite244;

import java.util.*;
public class HipHop implements Runnable {

    @Override
    public void run() {
        while(true) {
            String name = Thread.currentThread().getName();
            System.out.println(name);
            Random random = new Random();
            try {
                Thread.sleep(1000 + random.nextInt(2000));
            } catch (InterruptedException e) {
                break;
            }
        }

    }

    public static void main(String[] args) throws java.io.IOException {
        Thread hip = new Thread(new HipHop(), "hip");
        Thread hop = new Thread(new HipHop(), "hop");
        hip.start();
        hop.start();
        System.in.read();
        hip.interrupt();
        hop.interrupt();
        System.out.println("Ende");
        

    }

}
Es funktioniert leider immer noch nicht. Dies waren meine Überlegungen dabei: Das break sollte die umgebende while-Schleife beenden und damit die Methode run zuende führen.
Über die Methode interrupt() habe ich dieses im Grundkurs Java gelesen:
"...sendet ein Unterbrechungssignal an den Thread, für den die Methode aufgerufen wurde. Dieser Thread befindet sich dann im Zustand "unterbrochen". Ist der Thread blockiert durch den Aufruf von sleep, join oder wait, so wird der Zustand "unterbrochen" gelöscht und eine InterruptedException ausgelöst."
Gedacht hatte ich es mir so, dass die Methode interrupt die beiden Threads hip und hop unterbricht und diese Threads dann durch das break beendet werden. Nach dem Drücken der Enter-Taste passiert aber schlichtweg gar nichts.
Für etwas Unterstützung wäre ich dankbar.

Viele Grüße, Gina
 

rme

Top Contributor
Hallo :)

Bei mir funktioniert dein Code, mit Enter werden beide Threads beendet. Allerdings gibt es eine geringe Wahrscheinlichkeit, dass es nicht klappt: Es kann ja sein, dass sich die Ausführung gerade nicht in Sleep befindet und dann auch keine Exception auftritt - wenn das interrupted-Flag gesetzt ist und Sleep betreten wird, wirft es auch keine Exception. Üblicherweise benutzt man als Bedingung für die Schleife deshalb nicht einfach true, sondern fragt dort ab, ob das Interrupted-Flag noch nicht gesetzt wurde, damit die Schleife dann andernfalls unterbrochen wird.

Edit: Oh sorry, das stimmt gar nicht - wenn das interrupted-Flag beim Betreten von Sleep gesetzt ist, wirft es sofort die Exception. Ich glaube deshalb eher, dass das Problem daran liegt, wie du die Eingabe machst. Funktioniert System.in.read() bei dir denn anderswo? Lass dir mal testweise mit einer Ausgabe direkt nach System.in.read() ausgeben, ob main überhaupt an den Punkt dahinter gelangt.
 
Zuletzt bearbeitet:

Gina

Mitglied
Hallo!

Nun habe ich getestet, ob ich den Code nach dem System.in.read() überhaupt erreiche:
Java:
...
System.in.read();
System.out.println("X");
...
Das X wird nie ausgegeben. Ich habe extra noch einmal überprüft, ob ich überhaupt die Enter-Taste genommen habe und das Programm auf einem anderen PC ausprobiert. Das Problem bleibt. Könnte es an Eclipse liegen?

Viele Grüße, Gina
 

kaoZ

Top Contributor
Also mal zum Verständnis

mit
Code:
System.in.read();
wartet dein Programm in einem InputStream in der Konsole auf einen Integer.

demnach wird blockierend in einer Schleife darin verweilt bis du diese Eingabe in der Konsole tätigst.

Wenn du die Eingabe getätigt hast und diese bestätigst wird auch dein Programm weiter ausgeführt und dein Text wird ausgegeben.

Allerdings kann
Code:
System.in.read();
eine Exception werfen und gehört in einen Try/Catch block, bzw. sollte die Exception an andere Stelle propagiert werden .

außerdem frage ich mich warum du nicht

1. Einen Scanner zur Eingabe Erfassung nutzt
2. Den Wert den du per Eingabe einlesen willst nirgends zwischenspeicherst um ihn weiterverarbeiten zu können, denn mit deinem Aufruf von
Code:
System.in.read();
wird nichts anderes gemacht als den Wert dann wieder auf der Konsole auszugeben.

[EDIT]oder wird auch nach Bestätigung in der Konsole der Text nicht ausgegeben ?[/EDIT]

btw. selbst wenn du das System.in.read(); nur dazu verwenden solltest um in einer Schleife wartend zu verbringen um das Beenden der Threads zu initiieren , kannst du mit dem Aufruf von interrupt(); lediglich darum "bitten" das die Threads ihre Arbeit einstellen.

Ich könnte dir dazu z.B den Abschnitt Threads sicher beenden , aus dem Buch "Der Weg zum Java Profi" - von Michael Inden empfehlen , der dies wenn auch etwas komplex beschreibt, und aufzeigt warum z.B Threads sich in ihrer Ausführung nicht einfach so beenden lassen, und welche Möglichkeiten bestehen trotzdem das beenden eines Threads anzustoßen.

[TIPP]
Falls Interesse besteht kann ich dir nachher wenn ich vor Ort bin auch gern die Seiten ablichten und hier Posten ;)
[/TIPP]
 
Zuletzt bearbeitet:

rme

Top Contributor
Die interrupt-Methode ist doch genau die richtige Methode zum Beenden eine Threads. Dass der Thread dadurch nicht sofort beendet wird, ist richtig und gut so. Ansonsten wäre es nämlich nicht deterministisch, was dann passiert - man weiß ja gar nicht, wo sich der Thread gerade innerhalb des Codes gerade in der Ausführung befindet. Und da jeder Thread bestimmte Wartepunkte wie Thread.sleep(), Object.wait() oder irgendwas anderes blockierendes verwenden sollte, funktioniert das in allen Situation zuverlässig. Außerhalb von Wartepunkte finden nur Berechnungen statt, die üblicherweise nur ein paar Millisekunden dauern.

Die einzige Ausnahme würde ich bei Threads sehen, die durch sehr intensive Berechnungen wirklich lange dauern und trotzdem von außen beendet werden sollen. Aber auch da könnte man in jeder Iteration prüfen, ob das interrupted-Flag gesetzt ist. Wenn man mit Tricks dafür sorgt, dass ein Thread wirklich sofort beendet wird, schreibt man nicht-deterministischen Code.

Ich finde den Code von Gina weiterhin vollständig korrekt, das Problem liegt irgendwo an der Art, wie sie die Eingabe macht, da das System.in bei ihr nach dem Drücken von Enter nicht reagiert.
 

kaoZ

Top Contributor
OK, mir scheint ich habe mich unverständlich ausgedrückt ^^

selbstverständlich ist das initiieren eines Thread Endes über den Aufruf von
Code:
.interrupt();
vollkommen in Ordnung, so wie oben beschrieben allerdings eher suboptimal, alleine schon aus gründen nicht vernünftiger Abarbeitung der geworfenen Exceptions.

Der Vorschlag einen Auszug aus dem Buch zu posten diente lediglich der Veranschaulichung wie man es Optimieren könnte, hier wird z.B das beenden des Threads über eine Utility Klasse gehandhabt, welche sich dann auch um die Exceptions kümmert.

[EDIT]
Selbstverständlich ist es auch nicht sinnvoll einen Thread inmitten in seiner Bearbeitung zu Unterbrechen , da dies ja sonst wieder zu Inkonsistenzen führen könnte.
[/EDIT]

Ansonsten Spricht nichts dagegen, auch wenn ich nicht in einer endlos Schleife darauf warten würde das jemand mit Enter diese unterbricht, wie gesagt es gibt schönere Lösungsansätze das Flag für den Interrupt zu setzen :).

Falls dennoch Interesse besteht such ich den Anschnitt gerne mal raus
 
Zuletzt bearbeitet:

rme

Top Contributor
Hm.. Mich interessiert, warum du das obige Vorgehen suboptimal findest. Das Thread.sleep liefert einen eindeutigen Unterbrechungspunkt für die Schleife - wenn der Thread durch interrupt() unterbrochen wird, wird er also immer deterministisch während des sleep() unterbrochen. Die Exception signalisiert in diesem Fall diese Unterbrechung. Da der Thread bei Unterbrechung die Schleife verlassen soll, hat sie dort ein break geschrieben - das ist doch genau das Verhalten, das der Thread dann zeigen soll. Was würdest du dort denn sonst machen? Das Informieren des Benutzers oder die Ausgabe eines Stack-Traces sind in diesem Fall meiner Meinung nach unangebracht, da die Exception nicht unerwartet kam, sondern hier gezielt zur Signalisierung benutzt wird. Ich weiß, dass Exceptions nur für unerwartete Situation und nicht für das normale Programmverhalten benutzt werden sollten. Allerdings ist es aus Sichts des Sleep-Aufrufs ja tatsächlich ein Sonderfall, dass er "plötzlich" unterbrochen wird, deshalb finde ich das in Ordnung. Und im Übrigen gibt die Java-API das nunmal so vor. Es gab vorher ja mit stop, suspend usw. einen anderen Mechanismus, der dann durch diesen ersetzt wurde.

Als andere Variante fällt mir höchstens ein, dass man ein eigenes Flag einführt, das jemand außerhalb des Threads setzen kann, um den Thread zum Aufhören zu bitten. Dieses würde man dann wohl in der while-Schleife abfragen, um mit der Ausführung dann abzuschließen. Der Abbruchpunkt wäre dann auch deterministisch, nämlich nach der Schleife. Ein Nachteil wäre dann, dass der sleep-Aufruf nicht unterbrochen wird, und der Thread dadurch in der Schleife lange pausieren kann, bis er das Signal bemerkt. Und außerdem hätte man dann nur das interrupt-Flag nachprogrammiert.

Mich würde also interessieren, warum das obige suboptimal ist und wie du es verbessern würdest - insbesondere auch, welche Vorteile dadurch entstehen.
 

nvidia

Bekanntes Mitglied
Vernünftigerweise würde man es wohl so wie unten implementieren, d.h. den Inhalt des
Schleifenkörpers in das try-catch packen und im catch das Interrupt-Flag
wiederherstellen da dieses "gelöscht" wird und somit vll. ein "höherer" Thread nichts von der
Unterbrechung mitbekommt.

Java:
	@Override
	public void run() {
		while (!Thread.currentThread().isInterrupted()) {
			try {
				Thread.sleep(10000);
			} catch (InterruptedException e) {
				Thread.currentThread().interrupt();
			}
		}
	}
 
Zuletzt bearbeitet:

Gina

Mitglied
Hallo,

ich habe mein Programm nun zum Laufen (und zum Anhalten) gebracht. Das Problem war, dass ich nicht beachtet habe, dass man bei Eclipse den Focus dann auch in den Konsolenbereich legen muss. Das passiert mir nicht noch einmal.

Viele Grüße, Gina


@Danke-Button: wo finde ich denn diesen Button?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
B Thread / Prozess stoppen? Java Basics - Anfänger-Themen 22
O Thread aus dem Thread stoppen Java Basics - Anfänger-Themen 6
M Threads von Gui Thread starten und stoppen Java Basics - Anfänger-Themen 2
Screen Threads Wie thread stoppen/closen ? und wie GUI at runntime updaten? Java Basics - Anfänger-Themen 10
I Thread stoppen und starten Java Basics - Anfänger-Themen 3
A Jlayer: Wie sound stoppen der in einem Thread läuft Java Basics - Anfänger-Themen 7
S Thread stoppen ohne stop()? Java Basics - Anfänger-Themen 13
Dit_ Thread stoppen und wieder starten Java Basics - Anfänger-Themen 2
Dit_ Thread stoppen. Java Basics - Anfänger-Themen 15
O anonymen Thread stoppen Java Basics - Anfänger-Themen 4
G Thread stoppen? Java Basics - Anfänger-Themen 4
T Thread stoppen Java Basics - Anfänger-Themen 4
B Thread will einfach nicht stoppen Java Basics - Anfänger-Themen 12
loadbrain Thread stoppen Java Basics - Anfänger-Themen 7
7 Thread will nicht stoppen Java Basics - Anfänger-Themen 2
F Thread nach unaktivitätszeit stoppen Java Basics - Anfänger-Themen 7
N Thread soll nur einmal ausgeführt werden, aber wie stoppen? Java Basics - Anfänger-Themen 5
T Thread stoppen und wieder starten. Java Basics - Anfänger-Themen 4
G Thread stoppen Java Basics - Anfänger-Themen 7
Leyla Thread isInterrupt Java Basics - Anfänger-Themen 18
P Meldung aus Java-Klasse in Thread an aufrufende Klasse Java Basics - Anfänger-Themen 1
A Thread XML-Dateien zusammenfügen Java Basics - Anfänger-Themen 11
F influxdb Upload in eigenem Thread Java Basics - Anfänger-Themen 2
frager2345 Thread - Methoden synchronized deklarieren Java Basics - Anfänger-Themen 10
berserkerdq2 Größter unterschied von extends thread und implements runnable? Java Basics - Anfänger-Themen 2
T Thread beenden aus zweiter Klasse Java Basics - Anfänger-Themen 4
A Thread - Synchronized Java Basics - Anfänger-Themen 10
A Thread Producer - Consumer Java Basics - Anfänger-Themen 1
A Thread-Semhapore Java Basics - Anfänger-Themen 0
A Thread Exchanger Java Basics - Anfänger-Themen 22
A Thread-Cyclicbarrier Java Basics - Anfänger-Themen 4
B In einem Thread Endlosschleife beenden Java Basics - Anfänger-Themen 19
A Thread-Verklemmung Java Basics - Anfänger-Themen 10
A Thread-Schreibe-Lese-Problem Java Basics - Anfänger-Themen 4
A Thread find number Java Basics - Anfänger-Themen 8
F Thread.sleep() Java Basics - Anfänger-Themen 5
F Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 11 at main.main(main.java:11) Java Basics - Anfänger-Themen 2
A Thread Java Basics - Anfänger-Themen 3
M Exception in thread "main" java.util.NoSuchElementException Java Basics - Anfänger-Themen 2
A Thread Java Basics - Anfänger-Themen 8
B Compiler-Fehler Fehlermeldung Exception in thread, falsche Eingabewert Java Basics - Anfänger-Themen 2
M Thread-Zustände Java Basics - Anfänger-Themen 6
CptK For-Schleife in Thread nach jedem Durchlauf pausieren Java Basics - Anfänger-Themen 35
S Kriege Fehler "Exception in thread" beim Benutzen von SubStrings. Java Basics - Anfänger-Themen 2
B Endlosschleife Thread sauber beenden Java Basics - Anfänger-Themen 19
D Java Thread wartet nur ein mal Java Basics - Anfänger-Themen 1
D Java Thread wartet nur ein mal Java Basics - Anfänger-Themen 0
O Exception in thread "main" java.lang.ArithmeticException: / by zero Java Basics - Anfänger-Themen 4
C Thread und TimerTask, Verstädnisproblem Java Basics - Anfänger-Themen 10
amgadalghabra Sorting Thread Launcher Java Basics - Anfänger-Themen 3
B Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException Java Basics - Anfänger-Themen 8
A Thread Java Basics - Anfänger-Themen 4
A Thread Java Basics - Anfänger-Themen 1
A Thread Java Basics - Anfänger-Themen 0
R Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException Java Basics - Anfänger-Themen 5
S Compiler-Fehler Exception in thread "main" java.lang.Error: Unresolved compilation problem: Java Basics - Anfänger-Themen 6
L Liste in anderem Thread laden Java Basics - Anfänger-Themen 1
I Compiler-Fehler Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5 Java Basics - Anfänger-Themen 3
B Threads Thread sleep() Method einfache Frage Java Basics - Anfänger-Themen 8
W Thread Aufgabe - Vorgehensweise Java Basics - Anfänger-Themen 8
L Liste in anderem Thread laden Java Basics - Anfänger-Themen 0
J Threads PrograssBar update während thread Java Basics - Anfänger-Themen 13
D Compiler-Fehler Wert auf Datenbank übertragen und Sleep Thread Java Basics - Anfänger-Themen 3
Spencer Reid JavaFX Memory Thread.sleep Java Basics - Anfänger-Themen 1
S Thread.sleep mit JProgressBar Java Basics - Anfänger-Themen 1
ralfb1105 Frage zu Thread Synchronisation mit wait() und notify() Java Basics - Anfänger-Themen 3
R Exception in thread "main" java.lang.NullPointerException Java Basics - Anfänger-Themen 10
J JavaFX -> SocketIO -> Thread -> Update Label Java Basics - Anfänger-Themen 13
J Thread Handling Java Basics - Anfänger-Themen 9
A Problem mit Thread.sleep Java Basics - Anfänger-Themen 4
C Thread in Methode + raus aus der Schleife Java Basics - Anfänger-Themen 10
E Threads Thread in While-Schleife nur einmal starten Java Basics - Anfänger-Themen 2
F Daten von Thread an den aufrufenden zurückgeben Java Basics - Anfänger-Themen 22
C Compiler-Fehler Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2 Java Basics - Anfänger-Themen 3
B Thread Problem Java Basics - Anfänger-Themen 7
N KeyListener in Thread Java Basics - Anfänger-Themen 0
M Thread.sleep() Funktion Java Basics - Anfänger-Themen 1
W JLabel in Main aus Thread verändern. Java Basics - Anfänger-Themen 4
D Ausgeben welcher Thread gerade Arbeitet Java Basics - Anfänger-Themen 8
N Threads Thread-Fehler Java Basics - Anfänger-Themen 2
F Thread um Uhrzeit ausführen Java Basics - Anfänger-Themen 5
F Get/Post als eigener Thread mit Rückgabe Java Basics - Anfänger-Themen 5
J Exception in thread "main" Java Basics - Anfänger-Themen 1
F Thread der auf eine Queue wartet, sicher beenden Java Basics - Anfänger-Themen 4
B Animation mit Thread(s) Java Basics - Anfänger-Themen 23
I Thread.sleep (1000); Java Basics - Anfänger-Themen 1
M Threads Jede Klasse einem Thread zuweisen Java Basics - Anfänger-Themen 7
J Java Thread cancel() und wiederbeleben Java Basics - Anfänger-Themen 4
J BouncingBalls 1 Thread Java Basics - Anfänger-Themen 3
L Fehler: Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException Java Basics - Anfänger-Themen 4
J Timer oder Thread programmieren ? Java Basics - Anfänger-Themen 10
fLooojava Laufender Thread | Boolean ändern Java Basics - Anfänger-Themen 9
T Thread Pool mit Work Stealing Java Basics - Anfänger-Themen 1
R Java Thread Java Basics - Anfänger-Themen 10
J Welche Methoden laufen im neuen thread ?? Java Basics - Anfänger-Themen 9
S Java memory fehler: Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap spa Java Basics - Anfänger-Themen 5
K Thread - Methoden in die run Methode Schreiben Java Basics - Anfänger-Themen 5
N Threads Exception in thread "main"... Feher bei dem Versuch ein Radius zu berechnen Java Basics - Anfänger-Themen 4
A Code läuft nicht, Fehlermeldung Exception in thread "main" java.lang.Error: Unresolved compilation " Java Basics - Anfänger-Themen 11
V Threads Exception in Thread behandeln Java Basics - Anfänger-Themen 3

Ähnliche Java Themen

Neue Themen


Oben