I am working on a Java program and using Timer
objects to run tasks every few minutes or hours. This works fine in normal operations, but I am running into a problem with "Sleep mode" on Mac (maybe on other OSes, but I haven't tried yet).
Consider this code sample:
//Setup the timer to fire the ping worker (every 3 minutes)
_PingTimer.scheduleAtFixedRate(new TimerTask(){
public void run(){
Program.PingThread = new PingWorker(Settings.Username, Settings.UserHash, true, true);
Program.PingThread.CheckOpenPort = true;
Program.SwingExecutor.execute(Program.PingThread);
}
}, 0, 180000);
In normal operation this would fire every 3 minutes with enough accuracy (I'm not concerned about the exact second or anything). The problem with this is after sleeping the computer for a few hours or so it seems to just BLAST the system with backlogged timer requests.
It seems to be running all of the missed timer hits during sleep at once trying to make up for lost time.
Is there a way i can prevent this? I tried using synchronized
and some other thread techniques, but this only ensures that they aren't all running at the same time. They still continue to run one after another until the backlog is passed.
Thanks for any help you can provide!
One of the methods of the Timer class is the cancel() method. It is used to terminate the current timer and get rid of any presently scheduled tasks.
Timer and TimerTask are java util classes that we use to schedule tasks in a background thread. Basically, TimerTask is the task to perform, and Timer is the scheduler.
There it states: "Corresponding to each Timer object is a single backgroundthread that is used to execute all of the timer's tasks, sequentially." - so yes, each Timer has its own thread but if you schedule 2 tasks on the same timer they will be executed sequentially.
The cancel() method is used to cancel the timer task. The cancel() methods returns true when the task is scheduled for one-time execution and has not executed until now and returns false when the task was scheduled for one-time execution and has been executed already.
Have you looked at the API? It clearly states the following:
In fixed-rate execution, each execution is scheduled relative to the scheduled execution time of the initial execution. If an execution is delayed for any reason (such as garbage collection or other background activity), two or more executions will occur in rapid succession to "catch up." In the long run, the frequency of execution will be exactly the reciprocal of the specified period (assuming the system clock underlying Object.wait(long) is accurate).
This is one reason why you should consider using a ScheduledExecutorService. This link may also prove useful.
Use schedule
instead of scheduleAtFixedRate
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With