What is the equivalent of javascript setTimeout in Java?
Asked Answered
D

9

67

I need to implement a function to run after 60 seconds of clicking a button. Please help, I used the Timer class, but I think that that is not the best way.

Dross answered 11/10, 2014 at 5:32 Comment(1)
This question has some good relevant answers: https://mcmap.net/q/136291/-how-to-set-a-timer-in-javaNealson
B
22

"I used the Timer class, but I think that that is not the best way."

The other answers assume you are not using Swing for your user interface (button).

If you are using Swing then do not use Thread.sleep() as it will freeze your Swing application.

Instead you should use a javax.swing.Timer.

See the Java tutorial How to Use Swing Timers and Lesson: Concurrency in Swing for more information and examples.

Barozzi answered 11/10, 2014 at 6:39 Comment(1)
even though this is the accepted answer it is woefully outdated, especially since the advent of java 9. See the answer below about the delayedExecutorEmbrue
B
65

Asynchronous implementation with JDK 1.8:

public static void setTimeout(Runnable runnable, int delay){
    new Thread(() -> {
        try {
            Thread.sleep(delay);
            runnable.run();
        }
        catch (Exception e){
            System.err.println(e);
        }
    }).start();
}

To call with lambda expression:

setTimeout(() -> System.out.println("test"), 1000);

Or with method reference:

setTimeout(anInstance::aMethod, 1000);

To deal with the current running thread only use a synchronous version:

public static void setTimeoutSync(Runnable runnable, int delay) {
    try {
        Thread.sleep(delay);
        runnable.run();
    }
    catch (Exception e){
        System.err.println(e);
    }
}

Use this with caution in main thread – it will suspend everything after the call until timeout expires and runnable executes.

Bromine answered 25/4, 2016 at 14:2 Comment(5)
yeah don't do it this way - it will start too many threads, I think the CompletableFuture technique is betterBibliomania
CompletableFuture still creates a new Thread. See CompletableFuture.java#2745.Bromine
huh, is there a way to tell CompletableFuture to use a threadpool instead of creating a new thread each time? or does it already do that?Bibliomania
Even Java's built-in Timer class starts "too many threads": "A facility for threads to schedule tasks for future execution in a background thread." I think this way is actually pretty clean. It doesn't handle the repeat-execution case, but you could always have your task just call settimeout again at the end.Carrier
It's not precisely like javascript setTimeout - setTimeout returns id which can be used for cancelation via clearTimeoutPepys
H
41

Use Java 9 CompletableFuture, every simple:

CompletableFuture.delayedExecutor(5, TimeUnit.SECONDS).execute(() -> {
  // Your code here executes after 5 seconds!
});
Humus answered 23/11, 2018 at 20:26 Comment(3)
Snippet not working it shows the error: The method delayedExecutor(int, TimeUnit) is undefined for the type CompletableFutureVirgate
I think I made a mistake, it's for Java 9, not Java 8. Use Java 9 and everything is fine.Humus
for anyone working with java 9 and up this should be the accepted answerEmbrue
B
22

"I used the Timer class, but I think that that is not the best way."

The other answers assume you are not using Swing for your user interface (button).

If you are using Swing then do not use Thread.sleep() as it will freeze your Swing application.

Instead you should use a javax.swing.Timer.

See the Java tutorial How to Use Swing Timers and Lesson: Concurrency in Swing for more information and examples.

Barozzi answered 11/10, 2014 at 6:39 Comment(1)
even though this is the accepted answer it is woefully outdated, especially since the advent of java 9. See the answer below about the delayedExecutorEmbrue
M
16

Using the java.util.Timer:

new Timer().schedule(new TimerTask() {
    @Override
    public void run() {
        // here goes your code to delay
    }
}, 300L); // 300 is the delay in millis

Here you can find some info and examples.

Mehala answered 20/5, 2019 at 16:53 Comment(2)
Thanks, I also needed clearTimeout() alternative so usage is ... Timer timer = new Timer(); timer.schedule(...); timer.cancel();Bowel
It's still useful in 2023. Thanks!Brosine
P
9

You can simply use Thread.sleep() for this purpose. But if you are working in a multithreaded environment with a user interface, you would want to perform this in the separate thread to avoid the sleep to block the user interface.

try{
    Thread.sleep(60000);
    // Then do something meaningful...
}catch(InterruptedException e){
    e.printStackTrace();
}
Ponytail answered 11/10, 2014 at 5:42 Comment(0)
G
7

Do not use Thread.sleep as it will freeze your main thread, and not simulate setTimeout from JS.

You need to create and start a new background thread to run your code without stoping the execution of the main thread.

One example:


    new Thread() {
        @Override
        public void run() {
            try {
                this.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
            
            // your code here

        }
    }.start();
Grunberg answered 24/2, 2017 at 19:3 Comment(0)
B
4
public ScheduledExecutorService = ses;
ses.scheduleAtFixedRate(new Runnable() {
    run() {
            //running after specified time
    }
}, 60, TimeUnit.SECONDS);

It runs after 60 seconds from scheduleAtFixedRate. Check the ScheduledExecutorService documentation.

Bricebriceno answered 4/6, 2017 at 12:2 Comment(2)
Can you share how your solution is better than the others? And please also explain what your solution is doing rather than just pasting a piece of code.Renoir
the code creatore was not me. its oracle. better than me , their must explain. pleade refer to this link and read doc.docs.oracle.com/javase/7/docs/api/java/util/concurrent/…Bricebriceno
A
1

You should use Thread.sleep() method.

try {

    Thread.sleep(60000);
    callTheFunctionYouWantTo();
} catch(InterruptedException ex) {

}

This will wait for 60,000 milliseconds(60 seconds) and then execute the next statements in your code.

Ardys answered 11/10, 2014 at 5:36 Comment(0)
J
1

There is setTimeout() method in underscore-java library.

Code example:

import com.github.underscore.Underscore;
import java.util.function.Supplier;

public class Main {

    public static void main(String[] args) {
        final Integer[] counter = new Integer[] {0};
        Supplier<Void> incr =
            () -> {
                counter[0]++;
                return null;
            };
        Underscore.setTimeout(incr, 0);
    }
}

The function will be started in 100ms with a new thread.

Jug answered 1/4, 2016 at 15:14 Comment(1)
It is definitely inappropriate to use any sort of "sleep" (on the main or active thread) to do this sort of thing. (Nor does it call for the use of a thread.) Some sort of timeout, as suggested here, is definitely called-for. Also: in the timeout-handler, be sure that you verify that the condition-of-interest still exists! (Even if you "delete the timeout" when the condition no longer exists, there is still a miniscule timing-hole left that you cannot completely eliminate.)Dimmick

© 2022 - 2024 — McMap. All rights reserved.