Explain Codes LogoExplain Codes Logo

How do I make a delay in Java?

java
scheduledexecutorservice
lambda
thread-sleep
Nikita BarsukovbyNikita Barsukov·Aug 3, 2024
TLDR

Introduce a delay using Thread.sleep(milliseconds). But remember to add a try-catch block to manage InterruptedExceptions:

try { Thread.sleep(1000); // Wait for 1,000 milliseconds (also known as taking a quick coffee break ☕) } catch (InterruptedException ie) { Thread.currentThread().interrupt(); // Someone disturbed the coffee break! }

Be aware though, excessive sleeping can cause your application's UI to give you the cold shoulder (i.e., it freezes). So, ensure long pauses are always planned for (handled in separate threads).

In cases requiring precise timing and control for repetitive tasks, ScheduledExecutorService swings into action.

Delaying like a pro

Timing tasks like a clocksmith with ScheduledExecutorService

If you've got tasks that need to happen regularly, like a cuckoo clock (but hopefully less annoying🕰️), then you want to use ScheduledExecutorService.

You can create a shiny new instance of it using Executors.newSingleThreadScheduledExecutor(), and you can give it tasks using either scheduleAtFixedRate (which doesn't care how long the task takes) or scheduleWithFixedDelay (which starts the timer after the task finishes).

ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); Runnable myTask = () -> { // Insert task here (the kind you wouldn’t mind doing every couple of seconds!) }; scheduler.scheduleAtFixedRate(myTask, 0, 1, TimeUnit.SECONDS); // This task is prompt! Executes every 1 second, like a really stubborn preschooler asking "why"!

Avoiding drift like a bad Fast & Furious scene

To prevent a Fast & Furious level of drift when using Thread.sleep() in loops, make sure you count the execution time and adjust the sleep time like a Formula 1 pit-crew:

Lambdafying and retro compatibility

Java 8 — Don't repeat yourself, use lambdas!

In Java 8, lambda expressions are your new best friend. They simplify your syntax and make your code look smart and cool:

scheduler.scheduleWithFixedDelay(() -> { // Task here }, 0, 1, TimeUnit.SECONDS);

Back to the Future: Pre Java 8

If for some reason you're time-traveling and working with a version before Java 8, replace lambda expressions with anonymous inner classes. Not as sleek, but it’ll do the job:

scheduler.scheduleWithFixedDelay(new Runnable() { @Override public void run() { // Task here } }, 0, 1, TimeUnit.SECONDS);

Can I interrupt you for a moment?

Make sure to use protection... to handle InterruptedExceptions

When using Thread.sleep() in loops, things can get a bit hairy with InterruptedExceptions. So use a try-catch block inside the loop. Yes, it's like having an umbrella inside the house, but just in case:

while (!Thread.currentThread().isInterrupted()) { try { Thread.sleep(4000); // Just sleeping for 4 seconds (or in cat nap units 👀: 0.0115740741) } catch (InterruptedException ie) { Thread.currentThread().interrupt(); // Oops, the cat nap got interrupted! break; } // Repeat action }

More than a simple pause

Using wait to play hide and seek with your code

In synchronized code blocks, wait(milliseconds) is like playing a game of hide and seek with your code. If properly synchronized, the notify() or notifyAll() by other threads can end the game (interrupt the wait).

synchronized (monitor) { while (conditionIsNotMet) { monitor.wait(2000); // Wait for up to 2 seconds (like a short commercial break!) // ... Someone might call monitor.notify() } }

Swing timers: the UI-conscious approach

In Swing applications, don't use Thread.sleep(). That's like telling the UI to “talk to the hand”. Instead, make use of friendly Swing Timers. These are the cool kids that can schedule tasks and play nicely with the UI:

// Import javax.swing.Timer. (Yes, Swing has its own Timer. Fancy, right?) Timer timer = new Timer(delay, e -> { // Task to perform }); timer.setRepeats(false); // True if it’s a catchy song you want to put on repeat timer.start();

When using Thread.sleep() feels like walking on eggshells

Being delicate with Thread.sleep() in loops is a must, as it may lead to jitter or clock drift. Hence, ScheduledExecutorService shines here; it can schedule tasks with the precision of a Swiss watch.