How do I make a delay in Java?
Asked Answered
V

8

587

I am trying to do something in Java and I need something to wait / delay for an amount of seconds in a while loop.

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

I want to build a step sequencer.

How do I make a delay in Java?

Vassallo answered 8/6, 2014 at 8:26 Comment(5)
Use Thread.Sleep().Motor
Consider to use a TimerLandsturm
What is the purpose of waiting? Are you waiting for a certain event to happen? Make sure you understand what sleep() method doesDejadeject
@Tiny, it's NOT safe.Yorke
It is actually Thread.sleep(<milisecondsToSleep>). The s shouldn't be capitalized.Absorbing
S
1145

If you want to pause then use java.util.concurrent.TimeUnit:

TimeUnit.SECONDS.sleep(1);

To sleep for one second or

TimeUnit.MINUTES.sleep(1);

To sleep for a minute.

As this is a loop, this presents an inherent problem - drift. Every time you run code and then sleep you will be drifting a little bit from running, say, every second. If this is an issue then don't use sleep.

Further, sleep isn't very flexible when it comes to control.

For running a task every second or at a one second delay I would strongly recommend a ScheduledExecutorService and either scheduleAtFixedRate or scheduleWithFixedDelay.

For example, to run the method myTask every second (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");
}

And 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");
}
Semiconscious answered 8/6, 2014 at 8:42 Comment(8)
@Matthew Moisen I couldn't get this Java 8 example to run. What is App:: exactly? By changing myTask() to a runnable lambda it works: Runnable myTask = () -> {...};Katowice
It's a method reference @comfytoday - I suggest starting with the documentation.Semiconscious
TimeUnit.SECONDS.wait(1) is throwing IllegalMonitorStateException in Java 8.1 build 31 on Windows 6.3. Instead, I'm able to use Thread.sleep(1000) without a try/catch.Precast
You called wait not sleep @JohnMeyer. Be more careful.Semiconscious
In Java 8, in java.util.concurrent.TimeUnit you get Unhandled exception: java.lang.InterruptedExecution for the sleep(1)Katlynkatmai
You must surround the TimeUnit.SECONDS.sleep(1); with try catchKatlynkatmai
@ShaiAlon What can one usually have in that catch block ?Pensive
If anyone is still struggling with this function, make the enclosing function that calls sleep() throw InterruptedException with throws and catch it where the function is being called. @Pensive Or simply enclose that statement in a try-catch to catch the InterruptedException and print the stack trace.Squeaky
B
232

Use Thread.sleep(1000);

1000 is the number of milliseconds that the program will pause.

try {
  Thread.sleep(1000);
} catch (InterruptedException e) {
  Thread.currentThread().interrupt();
}
Bathos answered 8/6, 2014 at 8:28 Comment(5)
Don't forget to log the InterruptedException or you will never know this thread got interrupted.Pulchritude
I'm curious as to what the Thread.currentThread().interrupt(); does here.Stairs
see : "Why do we have to interrupt the thread again?" here : javaspecialists.eu/archive/Issue056.htmlEnshrine
If I read the link above correctly, thread.sleep() raises the interrupt flag. The try turns off the interrupt flag. Calling Thread.currentThread().interrupt(); raises the interrupt flag again. If other parts of your program (e.g dependencies) rely on threading/ or sleep as well, it will be looking for this nonexistent interrupt flag. tl;dr: Without Thread.currentThread().interrupt() invoked, you will introduce a nightmare bug to debug if other dependencies unknowingly use Thread.sleep() in their dependenciesTicklish
May be a noob question, but I don't understand why we need to catch the interrupt in the first place?Defense
T
33

Use this:

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

and, then you can call this method anywhere like:

wait(1000);
Tanagra answered 20/8, 2019 at 5:16 Comment(1)
What does Thread.currentThread().interrupt(); do? Why is it important?Auxiliaries
S
11

You need to use the Thread.sleep() call.

More info here: https://docs.oracle.com/javase/tutorial/essential/concurrency/sleep.html

Semi answered 8/6, 2014 at 8:28 Comment(0)
Y
7

Use Thread.sleep(100);. The unit of time is milliseconds

For example:

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]);
        }
    }
}
Yolande answered 14/11, 2018 at 17:37 Comment(0)
F
6

Using TimeUnit.SECONDS.sleep(1); or Thread.sleep(1000); Is acceptable way to do it. In both cases you have to catch InterruptedExceptionwhich makes your code Bulky.There is an Open Source java library called MgntUtils (written by me) that provides utility that already deals with InterruptedException inside. So your code would just include one line:

TimeUtils.sleepFor(1, TimeUnit.SECONDS);

See the javadoc here. You can access library from Maven Central or from Github. The article explaining about the library could be found here

Faust answered 19/8, 2018 at 18:23 Comment(2)
Using catch (InterruptedException e) { /* empty */ } is NOT a sensible solution here. At the very least, you should provide some log information. For more information about the subject, see javaspecialists.eu/archive/Issue056.htmlUpholster
@Upholster Actually due to your comment and comments from some other people I modified the method TimeUtils.sleepFor() and now it interrupts current thread. So, it is still convenient in a way that you don't need to catch the InterruptedException, but the interruption mechanism now works.Faust
B
3

I know this is a very old post but this may help someone: You can create a method, so whenever you need to pause you can type pause(1000) or any other millisecond value:

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

This is inserted just above the public static void main(String[] args), inside the class. Then, to call on the method, type pause(ms) but replace ms with the number of milliseconds to pause. That way, you don't have to insert the entire try-catch statement whenever you want to pause.

Bard answered 11/6, 2019 at 14:53 Comment(1)
Looking at the almost same answer by @Tanagra there is no Thread.currentThread().interrupt(); If it is important why is it not shown? - If it is not important why would it be inserted/omitted?Auxiliaries
O
3

There is also one more way to wait.

You can use LockSupport methods, e.g.:

LockSupport.parkNanos(1_000_000_000); // Disables current thread for scheduling at most for 1 second

Fortunately they don't throw any checked exception. But on the other hand according to the documentation there are more reasons for thread to be enabled:

  • Some other thread invokes unpark with the current thread as the target
  • Some other thread interrupts the current thread
Otte answered 5/12, 2021 at 13:42 Comment(1)
great answer, but it won't be bad to mention spurious wake-ups as a third reason.Daub

© 2022 - 2024 — McMap. All rights reserved.