Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resettable Java Timer

Tags:

java

timer

I'd like to have a java.utils.Timer with a resettable time in java.I need to set a once off event to occur in X seconds. If nothing happens in between the time the timer was created and X seconds, then the event occurs as normal.

If, however, before X seconds has elapsed, I decide that the event should occur after Y seconds instead, then I want to be able to tell the timer to reset its time so that the event occurs in Y seconds. E.g. the timer should be able to do something like:

Timer timer = new Timer();   timer.schedule(timerTask, 5000); //Timer starts in 5000 ms (X)  //At some point between 0 and 5000 ms...   setNewTime(timer, 8000);  //timerTask will fire in 8000ms from NOW (Y). 

I don't see a way to do this using the utils timer, as if you call cancel() you cannot schedule it again.

The only way I've come close to replicating this behavior is by using javax.swing.Timer and involves stopping the origional timer, and creating a new one. i.e.:

timer.stop(); timer = new Timer(8000, ActionListener); timer.start(); 

Is there an easier way??

like image 501
Lehane Avatar asked Aug 28 '08 10:08

Lehane


People also ask

How do you repeat a timer in Java?

Use timer. scheduleAtFixedRate() to schedule it to recur every two seconds: Schedules the specified task for repeated fixed-rate execution, beginning at the specified time.

Can you set a timer in Java?

Answer: The Timer class in Java belongs to Java. util. Timer package that provides a facility for threads to schedule a task that will be executed in the future in a background thread.

How do you make a 1 second timer in Java?

You can start the timer with one of the schedule methods like this: timer. schedule(new TimerTask() { @Override public void run() { //do your stuff here... } }, 0, 1000); This will start your timer with a delay of 0 milliseconds and repeat it after 1000 milliseconds.


2 Answers

According to the Timer documentation, in Java 1.5 onwards, you should prefer the ScheduledThreadPoolExecutor instead. (You may like to create this executor using Executors.newSingleThreadScheduledExecutor() for ease of use; it creates something much like a Timer.)

The cool thing is, when you schedule a task (by calling schedule()), it returns a ScheduledFuture object. You can use this to cancel the scheduled task. You're then free to submit a new task with a different triggering time.

ETA: The Timer documentation linked to doesn't say anything about ScheduledThreadPoolExecutor, however the OpenJDK version had this to say:

Java 5.0 introduced the java.util.concurrent package and one of the concurrency utilities therein is the ScheduledThreadPoolExecutor which is a thread pool for repeatedly executing tasks at a given rate or delay. It is effectively a more versatile replacement for the Timer/TimerTask combination, as it allows multiple service threads, accepts various time units, and doesn't require subclassing TimerTask (just implement Runnable). Configuring ScheduledThreadPoolExecutor with one thread makes it equivalent to Timer.

like image 128
Chris Jester-Young Avatar answered Sep 20 '22 19:09

Chris Jester-Young


If your Timer is only ever going to have one task to execute then I would suggest subclassing it:

import java.util.Timer; import java.util.TimerTask;  public class ReschedulableTimer extends Timer {     private Runnable  task;     private TimerTask timerTask;      public void schedule(Runnable runnable, long delay)     {         task = runnable;         timerTask = new TimerTask()         {             @Override             public void run()             {                 task.run();             }         };         this.schedule(timerTask, delay);     }      public void reschedule(long delay)     {         timerTask.cancel();         timerTask = new TimerTask()         {             @Override             public void run()             {                 task.run();             }         };         this.schedule(timerTask, delay);     } } 

You will need to work on the code to add checks for mis-use, but it should achieve what you want. The ScheduledThreadPoolExecutor does not seem to have built in support for rescheduling existing tasks either, but a similar approach should work there as well.

like image 33
David Sykes Avatar answered Sep 16 '22 19:09

David Sykes