Durch System.in.read() blockierten Thread stoppen

  • Themenstarter Themenstarter EditorEdi
  • Beginndatum Beginndatum
E

EditorEdi

Gast
Wie kann man einen Aufruf System.in.read() unterbrechen, ohne den Thread zu interrupten?

System.in.markSupported()
System.in.mark(readlimit)
System.in.reset()

unterstützt InputStream nicht...

Hintergrund: Der Benutzer soll in einer Konsolen-Anwendung eine Taste drücken können, woraufhin die Anwendung beendet werden soll; die Anwendung soll sich aber auch selbst beenden können.
 
Es müssen noch ein paar Dinge erledigt werden, bevor die Anwendung fertig ist.

Ist InputStream mit einer anderen Klasse verwendbar?

PS: Euer Captcha zu schwer.
 
Es ist unmöglich auf sichere Weise:
Is it possible to read from a Java InputStream with a timeout? - Stack Overflow

Workaround:
Es wird der InputStream System.in durch Reflection in seine Bestandteile zerlegt, bis zum FileInputStream, dessen read-Methode eine ClosedByInterruptException vorsieht. Die read-Methode wird innerhalb eines neuen Threads aufgerufen, und nach Verstreichen eines timeouts wird interrupt auf dem FileInputStream aufgerufen, wodurch wiederum die read-Methode eine ClosedByInterruptException wirft.

Trotzdem hilft mir das wenig...
 
Ja und? Das kann sie doch machen, bevor sie System.exit aufruft. Alternativ könnte man die Aktionen auch in einen ShutdownHook packen.

Das ShutdownHook-Wirrwarr kommt nicht in Frage. Es gibt mehrere Threads, die solange eine Schleife ausführen, wie ein Flag gesetzt ist. Das Programm ist beendet, wenn dieses Flag nicht mehr gesetzt ist und alle Threads alle Anweisungen bis zum Schleifenende ausgeführt haben.
 
Das ShutdownHook-Wirrwarr kommt nicht in Frage.
Was denn für ein Wirrwarr?
Es gibt mehrere Threads, die solange eine Schleife ausführen, wie ein Flag gesetzt ist. Das Programm ist beendet, wenn dieses Flag nicht mehr gesetzt ist und alle Threads alle Anweisungen bis zum Schleifenende ausgeführt haben.
Das gilt für alle Threads, außer für den, der auf System.in.read() wartet?

Vielleicht kannst Du in allen Thread zu Begin der run-Methode einen (globalen) Counter erhöhen und ihn am Ende der run-Methode (wenn also das Flag nicht mehr gesetzt ist) dekrementieren. Dabei kann dann jeder Thread prüfen, ob der Counter wieder auf 0 steht - dann kann er System.exit aufrufen, weil er dann ja offensichtlich der letzte Therad ist.
 
Gute Idee, AtomicInteger (oder wie die neuen Klassen heißen) wäre dafür geeignet; damit es nicht zum konkurrierenden Zugriff auf gemeinsame Ressourcen kommt. Trotzdem ist ein System.exit(0) nicht das, was ich mir vorstelle. Aber aus besagten Gründen wird es unmöglich sein, Konsoleneingaben ohne System.in zu lesen. 🙁
 
Wenn es so ist, dass die Anwendung beendet werden soll, wenn alle Worker-Threads beendet sind, auch wenn der Thread, der auf die Konsoleneingabe wartet, noch blockiert ist, dann mach den "Konsolen-Thread" doch zum Daemon.
 

Zurück
Oben