java: run a function after a specific number of seconds

JavaTimer

Java Problem Overview


I have a specific function that I want to be executed after 5 seconds. How can i do that in Java?

I found javax.swing.timer, but I can't really understand how to use it. It looks like I'm looking for something way simpler then this class provides.

Please add a simple usage example.

Java Solutions


Solution 1 - Java

new java.util.Timer().schedule( 
        new java.util.TimerTask() {
            @Override
            public void run() {
                // your code here
            }
        }, 
        5000 
);

EDIT:

javadoc says:

> After the last live reference to a Timer object goes away and all outstanding tasks have completed execution, the timer's task execution thread terminates gracefully (and becomes subject to garbage collection). However, this can take arbitrarily long to occur.

Solution 2 - Java

Something like this:

// When your program starts up
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();

// then, when you want to schedule a task
Runnable task = ....    
executor.schedule(task, 5, TimeUnit.SECONDS);

// and finally, when your program wants to exit
executor.shutdown();

There are various other factory methods on Executor which you can use instead, if you want more threads in the pool.

And remember, it's important to shutdown the executor when you've finished. The shutdown() method will cleanly shut down the thread pool when the last task has completed, and will block until this happens. shutdownNow() will terminate the thread pool immediately.

Solution 3 - Java

Example of using javax.swing.Timer

Timer timer = new Timer(3000, new ActionListener() {
  @Override
  public void actionPerformed(ActionEvent arg0) {
    // Code to be executed
  }
});
timer.setRepeats(false); // Only execute once
timer.start(); // Go go go!

This code will only be executed once, and the execution happens in 3000 ms (3 seconds).

As camickr mentions, you should lookup "How to Use Swing Timers" for a short introduction.

Solution 4 - Java

As a variation of @tangens answer: if you can't wait for the garbage collector to clean up your thread, cancel the timer at the end of your run method.

Timer t = new java.util.Timer();
t.schedule( 
        new java.util.TimerTask() {
            @Override
            public void run() {
                // your code here
                // close the thread
                t.cancel();
            }
        }, 
        5000 
);

Solution 5 - Java

My code is as follows:

new java.util.Timer().schedule(

    new java.util.TimerTask() {
        @Override
        public void run() {
            // your code here, and if you have to refresh UI put this code: 
           runOnUiThread(new   Runnable() {
                  public void run() {
                            //your code
         
                        }
                   });
        }
    }, 
    5000 
);

Solution 6 - Java

Your original question mentions the "Swing Timer". If in fact your question is related to SWing, then you should be using the Swing Timer and NOT the util.Timer.

Read the section from the Swing tutorial on "How to Use Timers" for more information.

Solution 7 - Java

you could use the Thread.Sleep() function

Thread.sleep(4000);
myfunction();

Your function will execute after 4 seconds. However this might pause the entire program...

Solution 8 - Java

ScheduledThreadPoolExecutor has this ability, but it's quite heavyweight.

Timer also has this ability but opens several thread even if used only once.

Here's a simple implementation with a test (signature close to Android's Handler.postDelayed()):

public class JavaUtil {
	public static void postDelayed(final Runnable runnable, final long delayMillis) {
		final long requested = System.currentTimeMillis();
		new Thread(new Runnable() {
			@Override
			public void run() {
				// The while is just to ignore interruption.
				while (true) {
					try {
						long leftToSleep = requested + delayMillis - System.currentTimeMillis();
						if (leftToSleep > 0) {
							Thread.sleep(leftToSleep);
						}
						break;
					} catch (InterruptedException ignored) {
					}
				}
				runnable.run();
			}
		}).start();
	}
}

Test:

@Test
public void testRunsOnlyOnce() throws InterruptedException {
	long delay = 100;
	int num = 0;
	final AtomicInteger numAtomic = new AtomicInteger(num);
	JavaUtil.postDelayed(new Runnable() {
		@Override
		public void run() {
			numAtomic.incrementAndGet();
		}
	}, delay);
	Assert.assertEquals(num, numAtomic.get());
	Thread.sleep(delay + 10);
	Assert.assertEquals(num + 1, numAtomic.get());
	Thread.sleep(delay * 2);
	Assert.assertEquals(num + 1, numAtomic.get());
}

Solution 9 - Java

All other unswers require to run your code inside a new thread. In some simple use cases you may just want to wait a bit and continue execution within the same thread/flow.

Code below demonstrates that technique. Keep in mind this is similar to what java.util.Timer does under the hood but more lightweight.

import java.util.concurrent.TimeUnit;
public class DelaySample {
    public static void main(String[] args) {
	   DelayUtil d = new DelayUtil();
       System.out.println("started:"+ new Date());
	   d.delay(500);
	   System.out.println("half second after:"+ new Date());
	   d.delay(1, TimeUnit.MINUTES); 
	   System.out.println("1 minute after:"+ new Date());
    }
}

DelayUtil Implementation

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class DelayUtil {
    /** 
    *  Delays the current thread execution. 
    *  The thread loses ownership of any monitors. 
    *  Quits immediately if the thread is interrupted
    *  
    * @param duration the time duration in milliseconds
    */
   public void delay(final long durationInMillis) {
      delay(durationInMillis, TimeUnit.MILLISECONDS);
   }

   /** 
    * @param duration the time duration in the given {@code sourceUnit}
    * @param unit
    */
    public void delay(final long duration, final TimeUnit unit) {
        long currentTime = System.currentTimeMillis();
        long deadline = currentTime+unit.toMillis(duration);
        ReentrantLock lock = new ReentrantLock();
        Condition waitCondition = lock.newCondition();
    
        while ((deadline-currentTime)>0) {
            try {
                lock.lockInterruptibly();    
                waitCondition.await(deadline-currentTime, TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
        		Thread.currentThread().interrupt();
        		return;
            } finally {
                lock.unlock();
            }
            currentTime = System.currentTimeMillis();
        }
    }
}



Solution 10 - Java

public static Timer t;

public synchronized void startPollingTimer() {
        if (t == null) {
            TimerTask task = new TimerTask() {
                @Override
                public void run() {
                   //Do your work
                }
            };
            
            t = new Timer();
            t.scheduleAtFixedRate(task, 0, 1000);
        }
    }

Solution 11 - Java

I think in this case :

import javax.swing.*;
import java.awt.event.ActionListener;

is the best. When the Question is prevent Ui stack or a progress not visible before a heavy work or network call. We can use the following methods (from my experience) :

Run a method after one Second :

 public static void startMethodAfterOneSeconds(Runnable runnable) {
        Timer timer = new Timer(1000, new ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent e) {
                runnable.run();
            }

        });
        timer.setRepeats(false); // Only execute once
        timer.start(); 
    }

Run a method after n second once, Non repeating :

public static void startMethodAfterNMilliseconds(Runnable runnable, int milliSeconds) {
    Timer timer = new Timer(milliSeconds, new ActionListener() {
        @Override
        public void actionPerformed(java.awt.event.ActionEvent e) {
            runnable.run();
        }

    });
    timer.setRepeats(false); // Only execute once
    timer.start(); 
}

Run a method after n seconds, and repeat :

 public static void repeatMethodAfterNMilliseconds(Runnable runnable, int milliSeconds) {
        Timer timer = new Timer(milliSeconds, new ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent e) {
                runnable.run();
            }

        });
        timer.setRepeats(true); // Only execute once
        timer.start(); 
    }

And the Usage :

 startMethodAfterNMilliseconds(new Runnable() {
            @Override
            public void run() {
                // myMethod(); // Your method goes here. 
            }
        }, 1000);

Solution 12 - Java

Perhaps the most transparent way is to use the postDelayed function of the Handler class the following way:

new Handler().postDelayed(this::function, 1000);

or you can implement the function inside, for example:

new Handler().postDelayed(() -> System.out.println("A second later"), 1000);

Where the first argument is the function, the second argument is the delay time in milliseconds. In the first example, the name of the called function is "function".

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionufkView Question on Stackoverflow
Solution 1 - JavatangensView Answer on Stackoverflow
Solution 2 - JavaskaffmanView Answer on Stackoverflow
Solution 3 - JavazponView Answer on Stackoverflow
Solution 4 - JavaDandalfView Answer on Stackoverflow
Solution 5 - Javauser2885850View Answer on Stackoverflow
Solution 6 - JavacamickrView Answer on Stackoverflow
Solution 7 - JavadaleView Answer on Stackoverflow
Solution 8 - JavaAlikElzin-kilakaView Answer on Stackoverflow
Solution 9 - JavaValchkouView Answer on Stackoverflow
Solution 10 - JavaAmol KView Answer on Stackoverflow
Solution 11 - JavaNoor HossainView Answer on Stackoverflow
Solution 12 - JavaGergő FazekasView Answer on Stackoverflow