Can anybody explain me What is difference between scheduleAtFixedRate() and schedule() methods in Timer Class with simple code example.
The schedule(TimerTask task,long delay,long period) method is used to schedule the specified task for repeated fixed-delay execution, beginning after the specified delay.
The scheduleAtFixedRate(TimerTask task,long delay,long period) method is used to schedule the specified task for repeated fixed-rate execution, beginning after the specified delay
Related
I was looking at javadoc of --> java.util.concurrent.ScheduledExecutorService.scheduleAtFixedRate
I have re-produced below the javadoc:
ScheduledFuture<?> java.util.concurrent.ScheduledExecutorService.scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given period; that is executions will commence after initialDelay then initialDelay+period, then initialDelay + 2 * period, and so on. If any execution of the task encounters an exception, subsequent executions are suppressed. Otherwise, the task will only terminate via cancellation or termination of the executor. If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute.
Parameters:
command the task to execute
initialDelay the time to delay first execution
period the period between successive executions
unit the time unit of the initialDelay and period parameters
Returns:
a ScheduledFuture representing pending completion of the task, and whose get() method will throw an exception upon cancellation
I understood that first time it would be enabled after initialDelay and then repeated after period. However, looking at highlighted section above, it seems frequency is increasing in-between the successive executions.
Is this the correct behaviour? If so, then the delay would get increased from previous executions?
Can anyone help clarify?
While scheduling tasks using java.util.TimerTask how i can make sure that run method will execute only after current execution is completed, otherwise tasks queue size will keep growing and eventually task will be executing always. i am beginner and looking help
Use ExecutorService#scheduleWithFixedDelay(). This will start the 'delay' when the current task finishes (as opposed to scheduleAtFixedRate())
Use a java.util.Timer with the TimerTask. One of these timer's two methods can be used:
schedule(TimerTask task, long delay, long period)
scheduleAtFixedRate(TimerTask task, long delay, long period)
Where:
task - task to be scheduled.
delay - delay in milliseconds before task is to be executed.
period - time in milliseconds between successive task executions.
Also, refer this article: What is the difference between schedule and scheduleAtFixedRate?
One of the recommended uses of the ScheduledExecutorService is as a direct replacement for the Timer class, as discussed in numerous StackOverflow topics already:
Java Timer vs ExecutorService?
Difference between TimerTask and Executors.newScheduledThreadPool(1)
What is the difference between schedule and scheduleAtFixedRate?
Android Timer schedule vs scheduleAtFixedRate
However, the naming conventions of the methods supported by ScheduledExecutorService and Timer, are not identical. For example, whereas they both have a scheduleAtFixedRate() method, the Timer method
schedule​(TimerTask task, long delay, long period)
does not have a namesake counterpart.
Is the ScheduledExecutorService method
scheduleWithFixedDelay​(Runnable command, long initialDelay, long delay, TimeUnit unit)
the one to use instead?
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html#scheduleAtFixedRate(java.lang.Runnable,%20long,%20long,%20java.util.concurrent.TimeUnit)
Creates and executes a periodic action that becomes enabled first
after the given initial delay, and subsequently with the given delay
between the termination of one execution and the commencement of the
next.
https://docs.oracle.com/javase/7/docs/api/java/util/Timer.html#schedule(java.util.TimerTask,%20long,%20long)
Schedules the specified task for repeated fixed-delay execution,
beginning after the specified delay. Subsequent executions take place
at approximately regular intervals separated by the specified period.
I would say - Yes ;-)
Timer#schedule(TimerTask, long, long) has no counterpart in ScheduledExecutorService or its implementation ScheduledThreadPoolExecutor. Although this method is documented as
repeated fixed-delay execution,
it bahaves fundamentally different than ScheduledThreadPoolExecutor#scheduleWithFixedDelay(...) and let alone ScheduledThreadPoolExecutor#scheduleAtFixedRate(...). I have explained the difference between all these methods more detailed as part of this answer.
for(Date timerDate1=startDate; timerDate1<=cal3.add(cal3.DATE,7);startDate=cal3.add(cal3.DATE,1))
{
long period=60*60*1000;
Timer timer = new Timer();
timer.schedule(new MyTask(),timerDate,period);
cal3.add(cal3.DATE,1);
}
Use timer.scheduleAtFixedRate
void java.util.Timer.scheduleAtFixedRate(TimerTask task, long delay, long period)
scheduleAtFixedRate
public void scheduleAtFixedRate(TimerTask task,
long delay,
long period)
Schedules the specified task for repeated fixed-rate execution, beginning after the specified delay. Subsequent executions take place at approximately regular intervals, separated by the specified period. 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).
Fixed-rate execution is appropriate for recurring activities that are sensitive to absolute time, such as ringing a chime every hour on the hour, or running scheduled maintenance every day at a particular time. It is also appropriate for recurring activities where the total time to perform a fixed number of executions is important, such as a countdown timer that ticks once every second for ten seconds. Finally, fixed-rate execution is appropriate for scheduling multiple repeating timer tasks that must remain synchronized with respect to one another.
Parameters: task - task to be scheduled. delay - delay in milliseconds before task is to be executed. period - time in milliseconds between successive task executions. Throws: IllegalArgumentException - if delay is negative, or delay + System.currentTimeMillis() is negative. IllegalStateException - if task was already scheduled or cancelled, timer was cancelled, or timer thread terminated.
Instead of a for-loop, use a single Timer, and pass your task to one of the scheduleAtFixedRate methods of Timer, with a period of TimeUnit.DAYS.toMillis(1).
Your task class should be constructed with a starting Date and the class should store that date in a field. In the class's run method, use a Calendar to check whether the current time, minus 7 days, is later than the task's start date, and if it is, call cancel() and return immedately.
When using
Timer.schedule(TimerTask task, long delay, long period)
(i.e. with fixed-delay execution), what happens if the specified TimerTask's run() method takes longer than period to complete? Is it possible that two concurrent TimerTask threads will be running because of this?
And if so, is there a way to avoid it?
Timer's documentation says the following:
Timer tasks should complete quickly. If a timer task takes excessive time to complete, it "hogs" the timer's task execution thread. This can, in turn, delay the execution of subsequent tasks, which may "bunch up" and execute in rapid succession when (and if) the offending task finally completes.
That is, concurrent TimerTask threads will not be running. The tasks will accumulate into a queue. This may or may not be appropriate (more likely, not).
Timer and TimerTask don't handle this sort of situation well. If you want to handle it better, then don't use those classes.
java.util.concurrent.ScheduledExecutorService provides two scheduling methods, scheduleAtFixedRate and scheduledWithFixedDelay, which govern what happens when tasks "bunch up".
scheduleAtFixedRate:
Creates and executes a periodic action
that becomes enabled first after the
given initial delay, and subsequently
with the given period; that is
executions will commence after
initialDelay then initialDelay+period,
then initialDelay + 2 * period, and so
on. If any execution of the task
encounters an exception, subsequent
executions are suppressed. Otherwise,
the task will only terminate via
cancellation or termination of the
executor. If any execution of this
task takes longer than its period,
then subsequent executions may start
late, but will not concurrently
execute.
scheduleWithFixedDelay:
Creates and executes a periodic action
that becomes enabled first after the
given initial delay, and subsequently
with the given delay between the
termination of one execution and the
commencement of the next. If any
execution of the task encounters an
exception, subsequent executions are
suppressed. Otherwise, the task will
only terminate via cancellation or
termination of the executor.
You can create ScheduledExecutorService instances using the Executors factory class.