Jak zrobić opóźnienie w Javie?

344

Próbuję zrobić coś w Javie i potrzebuję czegoś do oczekiwania / opóźnienia na kilka sekund w pętli while.

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++;
}

Chcę zbudować sekwencer kroków i jestem nowy w Javie. Jakieś sugestie?

ardb
źródło
19
Zastosowanie Thread.Sleep().
Tiny
2
Rozważ użycie Timera
PeterMmm,
2
Jaki jest cel czekania? Czy czekasz na określone wydarzenie? Upewnij się, że rozumiesz, co robi metoda sleep ()
artdanil
@ Tiny, to NIE jest bezpieczne.
Yousha Aleayoub,
12
Tak jest Thread.sleep(<milisecondsToSleep>). Nie snależy wielkich liter.
Benjamin

Odpowiedzi:

678

Jeśli chcesz wstrzymać, użyj java.util.concurrent.TimeUnit:

TimeUnit.SECONDS.sleep(1);

Spać przez sekundę lub

TimeUnit.MINUTES.sleep(1);

Spać przez minutę.

Ponieważ jest to pętla, stanowi to nieodłączny problem - dryf. Za każdym razem, gdy uruchamiasz kod, a następnie śpisz, trochę odpadasz od uruchamiania, powiedzmy, co sekundę. Jeśli jest to problem, nie używaj gosleep .

Co więcej, sleepnie jest zbyt elastyczny, jeśli chodzi o kontrolę.

Aby uruchamiać zadanie co sekundę lub z jednosekundowym opóźnieniem, zdecydowanie zaleciłbym a ScheduledExecutorServicei albo scheduleAtFixedRatelub scheduleWithFixedDelay.

Na przykład, aby uruchomić metodę myTaskco sekundę (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");
}

A w Javie 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");
}
Pająk Boris
źródło
1
@Matthew Moisen Nie mogłem uruchomić tego przykładu Java 8. Co to jest App :: dokładnie? Zmieniając myTask () na uruchamialną lambda, działa: Runnable myTask = () -> {...};
comfytoday
2
Jest to odwołanie do metody @comfytoday - sugeruję zacząć od dokumentacji .
Boris the Spider
TimeUnit.SECONDS.wait(1)rzuca IllegalMonitorStateExceptionw Java 8.1 build 31 na Windows 6.3. Zamiast tego mogę używać Thread.sleep(1000)bez próbowania / łapania.
John Meyer,
1
W Javie 8, w java.util.concurrent.TimeUnit dostajesz Unhandled exception: java.lang.InterruptedExecutionzasleep(1)
Shai Alon
1
Musisz otaczają TimeUnit.SECONDS.sleep(1);ztry catch
Shai Alon
148

Użyj Thread.sleep(1000);

1000 to liczba milisekund, które program zatrzyma.

try
{
    Thread.sleep(1000);
}
catch(InterruptedException ex)
{
    Thread.currentThread().interrupt();
}
Anju Aravind
źródło
5
Nie zapomnij zarejestrować wyjątku InterruptedException, bo nigdy nie dowiesz się, że ten wątek został przerwany.
m0skit0
12
Jestem ciekawy, co Thread.currentThread (). Interrupt (); robi tutaj.
Brent212,
1
patrz: „Dlaczego musimy ponownie przerwać wątek?” tutaj: javaspecialists.eu/archive/Issue056.html
Tristan
5

Użyj tego:

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

możesz wywołać tę metodę w dowolnym miejscu, np .:

        wait(1000);
Hecanet
źródło
3

Używanie TimeUnit.SECONDS.sleep(1);lub Thread.sleep(1000);akceptowalny sposób to zrobić. W obu przypadkach musisz złapać, InterruptedExceptionco sprawia, że ​​twój kod jest nieporęczny. Istnieje biblioteka Java Open Source o nazwie MgntUtils (napisana przeze mnie), która zapewnia narzędzie, które już zajmuje się InterruptedExceptionwewnątrz. Twój kod zawiera więc tylko jedną linię:

TimeUtils.sleepFor(1, TimeUnit.SECONDS);

Zobacz javadoc tutaj . Możesz uzyskać dostęp do biblioteki z Maven Central lub z Github . Artykuł wyjaśniający o bibliotece można znaleźć tutaj

Michael Gantman
źródło
2
Używanie NIEcatch (InterruptedException e) { /* empty */ } jest tutaj rozsądnym rozwiązaniem. Przynajmniej powinieneś podać jakieś informacje z dziennika. Aby uzyskać więcej informacji na ten temat, zobacz javaspecialists.eu/archive/Issue056.html
Marco13,
3

Posługiwać się Thread.sleep(100); . Jednostką czasu są milisekundy

Na przykład:

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
źródło
1

Wiem, że jest to bardzo stary post, ale może to komuś pomóc: możesz utworzyć metodę, więc za każdym razem, gdy musisz zrobić pauzę, możesz wpisać pause(1000)dowolną inną milisekundę:

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

Zostało to wstawione tuż nad public static void main(String[] args)klasą. Następnie, aby wywołać metodę, wpisz, pause(ms)ale zamień, msliczbę milisekund do wstrzymania. W ten sposób nie musisz wstawiać całej instrukcji try-catch, gdy chcesz wstrzymać.

dominic03
źródło