Java: wie zum Abbrechen eines Threads Lesen aus dem System.in
Ich habe ein Java-thread:
class MyThread extends Thread {
@Override
public void run() {
BufferedReader stdin =
new BufferedReader(new InputStreamReader(System.in));
String msg;
try {
while ((msg = stdin.readLine()) != null) {
System.out.println("Got: " + msg);
}
System.out.println("Aborted.");
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
In einem anderen thread, wie kann ich das Abbrechen der stdin.readline()
Aufruf in diesem thread, damit dieser thread Drucke Aborted.
? Ich habe versucht System.in.close()
, aber das macht keinen Unterschied, stdin.readline()
ist immer noch blockiert.
Ich bin daran interessiert, Lösungen ohne
- busy waiting (weil das brennt 100% CPU);
- schlafen (weil dann das Programm nicht sofort reagieren auf
System.in
).
- Interessant. Es wäre auch interessant zu wissen, wie Sie zum Abbrechen eines thread hören auf eingehende client-socket-Daten. Hoffentlich die Lösung ist ziemlich ähnlich zu diesem problem 🙂
- Dies ist eine mehr Allgemeine Frage, dass das Lesen vom stdin - java.io-Zeug ist die Blockierung I/O, und es gibt viele bestehende Fragen über dieses allgemeinere problem.
- Für Steckdosen, ich habe eine Lösung: die Schließung der socket in einem anderen thread macht das
readLine
imMyThread
erhebenSocketException
mit"Socket closed"
. So kann ich AbbrechenMyThread
diese Weise. - Schön! vielen Dank für das teilen 🙂
Du musst angemeldet sein, um einen Kommentar abzugeben.
Meine erste Reaktion ist, dass eine thread und
System.in
wirklich nicht zusammen gehen.Also zuerst aufgeteilt, so dass der thread code nicht berühren Sie eine beliebige statische einschließlich
System.in
.Einen thread liest aus
InputStream
und geht in einen Puffer. Übergeben Sie einInputStream
in Ihre bestehenden thread, liest aus dem Puffer aber auch Prüfungen, die man noch nicht abgebrochen.stdin.readLine()
. Könnten Sie das bitte näher erläutern?Heinz Kabutz newsletter zeigt, wie Abbruch
System.in
liest mit einem Puffer undExecutorService
.Nun, ich weiß nicht, ob dieser Ansatz Lecks, ist das nicht tragbar ist oder nicht-offensichtliche Nebenwirkungen. Persönlich würde ich zögern, es zu benutzen.
Sie in der Lage sein könnte, etwas zu tun mit NIO-Kanäle und Datei-Deskriptoren - meine eigenen versuche mit Ihnen nicht nachzugeben keine Ergebnisse.
ExecutorService
, wie du es beschreibst, würde auf jeden Fall funktionieren, aber ich bin noch auf der Suche nach etwas weniger hässlich.Thread.sleep(200)
... nicht sicher, warum dies ist die top-Antwort gestimmt.Wie etwa...
Einen thread, wo
stdInch.readline()
aufgerufen wird, wird nun unterbrochen und die readline() wirft einejava.nio.channels.ClosedByInterruptException
.JavaDoc für BufferedReader.readLine:
Basierend auf dieser, ich glaube nicht, dass es jemals wieder null (kann System.in eigentlich geschlossen werden, ich glaube nicht, dass es jemals zurückkehrt Ende stream???), also die while-Schleife nicht beendet. Der übliche Weg zu stoppen, ein thread ist entweder eine Boolesche variable in einer Schleife, Bedingung und ändern Sie es von außerhalb des Threads, oder rufen Sie die Thread-Objekte' interrupt() -Methode (funktioniert nur, wenn der thread wait():ing oder sleep():ing, oder in einer blockierenden Methode throws InterruptedException). Sie können auch überprüfen, ob der Faden unterbrochen wurde, mit isInterrupted().
Edit: Hier ist eine einfache Implementierung unter Verwendung
isInterrupted()
undinterrupt()
. Der main-thread wartet 5 Sekunden, bevor die Unterbrechung der worker-thread. In diesem Fall worker-thread ist im Grunde busy-waiting, also es ist nicht so gut (Schleifen alle die Zeit und überprüfenstdin.ready()
könnten Sie natürlich lassen Sie den worker-thread schlafen für eine Weile, wenn keine weitere Eingabe bereit):Es scheint, gibt es keinen Weg, um tatsächlich zu unterbrechen BufferedReader wenn es blockiert readline, oder zumindest konnte ich nicht finden (mit System.in).
myThread.interrupt()
nicht unterbrechenreadLine()
Anruf aufSystem.in
, auch nicht nachSystem.in.close()
.Haben Sie versucht:
Die interrupt-Methode wirft einen InterrupedtException und du kannst mit der code danach.
myThread.interrupt()
macht keinen Unterschied.stdin.readLine()
noch gesperrt ist, wartet für mehr input zu LesenSystem in
.Was ist die Definition eines Feldes in deinem obigen thread-Klasse definition wie:
System.in
.abortThread
würde Abbruch der AufrufSystem.in.readline()
.MyThread
warten, bis die nächste Zeile, ohne busy waiting (100% CPU-Nutzung)?