Einfacher Sleep Befehl in Java

Hallo,

ich habe wirklich eine Stunde im Internet gesucht und viele Codeschnipsel getestet aber die meisten Sleep oder Wait Befehle in Java sorgen dafür das das Programm alle Pausierungen auf einmal macht und dann keine Zwischenschritte anzeigt. Ich will so etwas super simples wie in C++ machen. (Eine Art Textadventure)

textField(“Eine Sekunde vergeht.”);
Sleep(1000) // 1s warten
textField(“Mehr Zeit vergeht.”);
Sleep(1500) // 1,5s warten
textField(“Blar.”);
Sleep(1000) // 1s warten

Wenn ich Sleep mit Thread oder try catch und dem kram mache kommt immer nur eine Textmeldung.

Die Methode Sleep bekomm ich nicht hin.

Das funktioniert:

    public static void main(String... args) {
        System.out.println("Eine Sekunde vergeht.");
        sleep(1000);
        System.out.println("Mehr Zeit vergeht.");
        sleep(1500);
        System.out.println("Blar.");
        sleep(1000);
    }

    private static void sleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException ignored) {
        }
    }
}```

“Textfield” deutet darauf hin, dass da irgendwas im GUI passiert. Poste mal mehr code, wahrscheinlich blockierst du den Event-Disptatch-Thread, d.h. das GUI zeigt nur den letzten Status an

ich pass das mal ein bischen an

private static Exception sleep(long millis) {
    try {
        Thread.sleep(millis);
    } catch (InterruptedException ignored) {
        return ignored;
    }
    return null;
}

dann kann man zumindest noch die Exception behandeln - wenn man will

Da sehe ich dann aber schon fast keinen Vorteil mehr als direkt Thread.sleep() an der Stelle aufzurufen, wo ich will, anstelle von der Funktion die es nur weiterreicht.

Es jedoch in eine gesonderte Funktion packen um dort dann die Fehlerbehandlung zu machen (ob einfach ignorieren oder in einer anderen Form) finde ich dann Sinnvoll, vor allem wenn man es mehrfach verwenden will, mit dem selben Fehlerverhalten.

[li]Nie Nie Nie null zurück geben, wenn es kein legaler Wert der Ergebnismenge ist.
[/li][li]Rückgabewerte von Methoden nicht zur Signalisierung von Fehlerzuständen nutzen, genau dass sollen Exceptions ja umgehen
[/li][li]Exceptions nie stillschweigend ignorieren, entweder in eigene (Runtime-)Exceptions wandeln oder wenigstens mit e.printStackTrace() loggen
[/li][/ol]
[/SPOILER]
bye
TT

Bei den ersten zwei Punkten stimme ich dir zu. Aber beim dritten gibt es schon Fälle, wo es sinnvoll ist, die Exception stillschweigend zu ignorieren, daher kann man das „nie“ so nicht stehen lassen.
Gerade die InterruptedException ist ein guter Kandidat für eine ignorierte Exception.
Beispiel: Wenn ein Thread sowieso beendet wird, wenn die InterruptedException fliegt (weil die blockierende und jetzt unterbrochene Methode sowieso die letzte im Thread war), dann braucht man sie nicht zu verarbeiten, sondern kann den Thread einfach beenden lassen.

Das Beispiel hier im Thread ist natürlich kein Fall, auf den das zutrifft. Wahrscheinlich wäre ein Thread.currentThread().interrupt(); angebrachter, als die Exception zu ignorieren.

Wurde irgendwo definiert das null nicht Element der Ergebnismenge ist?

Bei der Methode gibt es irgendwie einen Sonderfall. Im Grunde kapselt die Methode das gesamte Geraffel (den ich sowieso noch nie benötigt habe) um den Sleep (worum es [mehr oder weniger] ursprünglich ging). Ich hätte alternativ auch ein Bool zurück geben können. Dummerweise gibt es da zwei verschiedene Exceptions. Das gesamte Ergebnis dieser Methode lässt sich nun als Einzeiler schreiben, wenn man die Exceptions bearbeiten will.

Exception ex = Helper.sleep(1000);
if (ex != null) handleException(ex);

Würde an der Stelle mit Bool in der Tat besser aussehen. Nur bekommen wir da Probleme mit Punkt 3

Da muss ich Dir 100% Recht geben. Nur hast ist das eine interne/eigene (VS-NFD, quasi) Methode. Da Du aber nicht weis mit welchem Framework der Kunde das geloggt haben will, kannst Du in der Methode nicht loggen. Falls doch kannst Du bei jedem Kunden die Methode umbasteln, damit das mit dem Logging-Framework des Kunden läuft.

Dazu würde bei mir auch nur sleep() einfallen. Mein Einzeiler dazu

try {Thread.sleep(1000); } catch(Exception ex) { /* !! DOUH !! */ }

[quote=mogel]Wurde irgendwo definiert das null nicht Element der Ergebnismenge ist?[/quote]Anders rum wird aber ein Schuh draus, null darf nur dann zurückgegeben werden, wenn es ausdrücklich als “natürliches” Element der Ergebnismenge entsteht (was äußerst selten der Fall ist) und der Aufrufer keine Sonderbehandlung dafür machen muss. Alles ander führt ehr früher als später zu einer schicken NPE und zwar in der Produktion, weil testen tut man sowas ja nicht…

[quote=mogel;85130]Bei der Methode gibt es irgendwie einen Sonderfall. […] Ich hätte alternativ auch ein Bool zurück geben können.[/quote]Besser wäre aber eine einge Exception, die könnte auch von RuntimeException ableiten. Dann muss ich mich erst in der Thread-Eingangsmethode wieder darum kümmern. Boolean-Rückgabewerte als Erfolgssignalisierung führen zu tief geschachtelten if-Kaskaden über mehrere Methoden-Aufrufe hinweg und behindern das (automatisierte) Refactoring.

[quote=mogel;85130]Da muss ich Dir 100% Recht geben. Nur hast ist das eine interne/eigene (VS-NFD, quasi) Methode. Da Du aber nicht weis mit welchem Framework der Kunde das geloggt haben will, kannst Du in der Methode nicht loggen.[/quote]Dafür gibt’s slf4j.

bye
TT

Mir fällt da schon noch ein bisschen mehr zu ein:

public void run() {
    try {
        while (!Thread.currentThread().isInterrupted()) {
            Object o = blockingQueue.take();
            doSomethingUseful(o);
        }
    } catch (InterruptedException ignored) {
    }
}```


[quote=Timothy_Truckle;85132]Anders rum wird aber ein Schuh draus, `null` darf nur dann zurückgegeben werden, wenn es ausdrücklich als "natürliches" Element der Ergebnismenge entsteht (was äußerst selten der Fall ist) und der Aufrufer keine Sonderbehandlung dafür machen muss. Alles ander führt ehr früher als später zu einer schicken NPE und zwar in der Produktion, weil testen tut man sowas ja nicht...[/quote]
Und **wenn** `null` zur Ergebnismenge gehört, kann man die Methode mit `@Nullable` annotieren. Dank statischer Codeanalyse kann man die meisten Fehler damit vermeiden.


Aber das ist für dieses simple Beispiel alles ein Overkill. Die Exception wird an dieser Stelle sowieso nicht geworfen werden. Und wenn doch... na und? Den TO interessiert das hier alles sicherlich nicht.

[quote=cmrudolph]Den TO interessiert das hier alles sicherlich nicht.[/quote]Stimmt.
Aber @mogel s “Lösung” darf man einfach nicht unkommentiert stehen lassen.

bye
TT

[QUOTE=Timothy_Truckle]
[li]Rückgabewerte von Methoden nicht zur Signalisierung von Fehlerzuständen nutzen, genau dass sollen Exceptions ja umgehen[/li][/QUOTE]
so allgemein so eine Regel überhaupt ist, ist sie für normale Methoden gedacht, die Wert xy oder -1 zurückgeben können

es kann trotzdem Methoden geben die direkt Exceptions thematisieren, sie etwa zusammenbauen,
selbstverständlich darf man Exceptions zurückgeben

hier ist das Wesen der Methode zwar Thread.sleep(), aber Unterbrechung/ Exceptionhandling dazu elementarer Bestandteil, auch erlaubt,


[quote=mogel;85130]Ergebnis dieser Methode lässt sich nun als Einzeiler schreiben, wenn man die Exceptions bearbeiten will.

    if (ex != null) handleException(ex);```[/quote]
das if kann ruhig weggelassen werden, handleException() darauf prüfen und evtl. gleich abbrechen,

`handleException(Helper.sleep(1000));`
oder eine angepasste Methode `sleepHE(1000);` 
die sich darum intern kümmert sind die logischen Folgen

Das Warten geht am schnellsten, wenn man es in einen eigenen Thread auslagert…

Tut mir leid für die späte Antwort. Marco13 hat Recht, mein Problem ist anscheinend, dass ich eben ein Textfeld im GUI meines in XDEV programmierten Fensters anspreche. XDEV ließ mich folgenden Button programmieren.

	{
		// 38 Wiederholungen mit Pausen davor/dazwischen!
		if (sofort)
		{
			for (int i = 0; i < 38; i++)
			{
				sleep(1000);
				CheckAll();
			}
		}
	}//```

Wenn ich jetzt TextField durch cmrusolphs System.out.println("Eine Sekunde vergeht."); ersetze funktioniert es ja. Die Konsole lässt sich permanent updaten. Aber meine GUI eben nicht. Der ganze Code ist in einer einzigen "public class main extends XdevWindow". Darin ist auch cmrusolphs sleep() Funktion und meine Funktion CheckAll(), die aber keine Rolle spielen sollte, in der stehen einfach viele Berechnungen und am Ende jedesmal sowas wie TextField.SetText("xy");

ein ActionListener darf nur eine Aktion von wenigen ms enthalten oder muss seine Arbeit in einen separaten Thread/ SwingWorker ausführen,
im ActionListener nur diesen Thread starten