Wie mache ich eine Verzögerung in Java?

343

Ich versuche etwas in Java zu tun und ich brauche etwas, um einige Sekunden in einer while-Schleife zu warten / zu verzögern.

while (true) {
    if (i == 3) {
        i = 0;
    }

    ceva[i].setSelected(true);

    // I need to wait here

    ceva[i].setSelected(false);

    // I need to wait here

    i++;
}

Ich möchte einen Step-Sequenzer bauen und bin neu in Java. Irgendwelche Vorschläge?

ardb
quelle
19
Verwenden Sie Thread.Sleep().
Winzig
2
Erwägen
2
Was ist der Zweck des Wartens? Warten Sie auf ein bestimmtes Ereignis?
Stellen
@ Winzig, es ist nicht sicher.
Yousha Aleayoub
12
Es ist tatsächlich Thread.sleep(<milisecondsToSleep>). Das ssollte nicht groß geschrieben werden.
Benjamin

Antworten:

677

Wenn Sie pausieren möchten, verwenden Sie java.util.concurrent.TimeUnit:

TimeUnit.SECONDS.sleep(1);

Eine Sekunde schlafen oder

TimeUnit.MINUTES.sleep(1);

Eine Minute schlafen.

Da dies eine Schleife ist, stellt dies ein inhärentes Problem dar - Drift. Jedes Mal, wenn Sie Code ausführen und dann schlafen, werden Sie beispielsweise jede Sekunde ein wenig vom Laufen abweichen. Wenn dies ein Problem ist, verwenden Sie es nicht sleep.

Darüber hinaus sleepist nicht sehr flexibel, wenn es um Kontrolle geht.

Um eine Aufgabe jede Sekunde oder mit einer Verzögerung von einer Sekunde auszuführen, würde ich dringend ein ScheduledExecutorServiceund entweder scheduleAtFixedRateoder empfehlen scheduleWithFixedDelay.

So führen Sie die Methode beispielsweise myTaskjede Sekunde aus (Java 8):

public static void main(String[] args) {
    final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
    executorService.scheduleAtFixedRate(App::myTask, 0, 1, TimeUnit.SECONDS);
}

private static void myTask() {
    System.out.println("Running");
}

Und in Java 7:

public static void main(String[] args) {
    final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
    executorService.scheduleAtFixedRate(new Runnable() {
        @Override
        public void run() {
            myTask();
        }
    }, 0, 1, TimeUnit.SECONDS);
}

private static void myTask() {
    System.out.println("Running");
}
Boris die Spinne
quelle
1
@ Matthew Moisen Ich konnte dieses Java 8-Beispiel nicht ausführen. Was ist App :: genau? Durch Ändern von myTask () in ein ausführbares Lambda funktioniert es: Ausführbares myTask = () -> {...};
Comfytoday
2
Es ist eine Methodenreferenz @comfytoday - ich schlage vor, mit der Dokumentation zu beginnen .
Boris die Spinne
TimeUnit.SECONDS.wait(1)wirft IllegalMonitorStateExceptionin Java 8.1 Build 31 unter Windows 6.3. Stattdessen kann ich Thread.sleep(1000)ohne Try / Catch verwenden.
John Meyer
1
In Java 8, in java.util.concurrent.TimeUnit erhalten Sie Unhandled exception: java.lang.InterruptedExecutionfür diesleep(1)
Shai Alon
1
Sie müssen die TimeUnit.SECONDS.sleep(1);mittry catch
Shai Alon
148

Verwenden Sie Thread.sleep(1000);

1000 ist die Anzahl der Millisekunden, die das Programm pausiert.

try
{
    Thread.sleep(1000);
}
catch(InterruptedException ex)
{
    Thread.currentThread().interrupt();
}
Anju Aravind
quelle
5
Vergessen Sie nicht, die InterruptedException zu protokollieren, sonst werden Sie nie erfahren, dass dieser Thread unterbrochen wurde.
m0skit0
12
Ich bin gespannt, was der Thread.currentThread (). Interrupt (); tut hier.
Brent212
1
siehe: "Warum müssen wir den Thread erneut unterbrechen?" hier: javaspecialists.eu/archive/Issue056.html
Tristan
4

benutze das:

public static void wait(int ms){
        try
        {
            Thread.sleep(ms);
        }
        catch(InterruptedException ex)
        {
            Thread.currentThread().interrupt();
        }
    }

Dann können Sie diese Methode wie folgt aufrufen:

        wait(1000);
Hecanet
quelle
3

Verwenden von TimeUnit.SECONDS.sleep(1);oder Thread.sleep(1000);ist ein akzeptabler Weg, dies zu tun. In beiden Fällen müssen Sie abfangen InterruptedException, was Ihren Code sperrig macht. Es gibt eine Open Source-Java-Bibliothek namens MgntUtils (von mir geschrieben), die ein Dienstprogramm bereitstellt, das sich bereits mit dem InterruptedExceptionInneren befasst . Ihr Code würde also nur eine Zeile enthalten:

TimeUtils.sleepFor(1, TimeUnit.SECONDS);

Sehen Sie den Javadoc hier . Sie können von Maven Central oder von Github aus auf die Bibliothek zugreifen . Den Artikel zur Bibliothek finden Sie hier

Michael Gantman
quelle
2
Die Verwendung catch (InterruptedException e) { /* empty */ }ist hier KEINE sinnvolle Lösung. Zumindest sollten Sie einige Protokollinformationen angeben. Weitere Informationen zu diesem Thema finden Sie unter javaspecialists.eu/archive/Issue056.html
Marco13
3

Verwenden Sie Thread.sleep(100);. Die Zeiteinheit ist Millisekunden

Zum Beispiel:

public class SleepMessages {
    public static void main(String args[])
        throws InterruptedException {
        String importantInfo[] = {
            "Mares eat oats",
            "Does eat oats",
            "Little lambs eat ivy",
            "A kid will eat ivy too"
        };

        for (int i = 0;
             i < importantInfo.length;
             i++) {
            //Pause for 4 seconds
            Thread.sleep(4000);
            //Print a message
            System.out.println(importantInfo[i]);
        }
    }
}
Bachan Joseph
quelle
1

Ich weiß, dass dies ein sehr alter Beitrag ist, aber dies kann jemandem helfen: Sie können eine Methode erstellen. Wenn Sie also eine Pause einlegen müssen, können Sie pause(1000)einen anderen Millisekundenwert eingeben:

public static void pause(int ms) {
    try {
        Thread.sleep(ms);
    } catch (InterruptedException e) {
        System.err.format("IOException: %s%n", e);
    }
}

Dies wird direkt über public static void main(String[] args)der Klasse eingefügt . Geben Sie dann zum Aufrufen der Methode Folgendes ein pause(ms), ersetzen Sie es jedoch durch msdie Anzahl der Millisekunden, die angehalten werden sollen. Auf diese Weise müssen Sie nicht die gesamte try-catch-Anweisung einfügen, wenn Sie eine Pause einlegen möchten.

dominic03
quelle