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?
Related
I ask this question because there is a command that executes multiple times. Does it return a ScheduledFuture every time the command executes or does it return a single ScheduledFuture at some point?
Only a single ScheduledFuture<?> is returned upon scheduling the Runnable command.
According to the Javadoc, scheduleAtFixedRate returns
a ScheduledFuture representing pending completion of the series
of repeated tasks
You can also see this in the method signature:
ScheduledFuture<?> scheduleAtFixedRate​(Runnable command, long initialDelay, long period, TimeUnit unit)
The Runnable command continues to be executed according to the configured interval without further intervention.
The sequence of task executions continues indefinitely until one of
the following exceptional completions occur:
The task is explicitly cancelled via the returned future.
The executor terminates, also resulting in task cancellation.
An execution of the task throws an exception.
Having a single ScheduledFuture returned by scheduleAtFixedRate provides a useful mechanism to programmatically discontinue all future scheduled executions of Runnable command through a call to cancel on the Future.
I have a ScheduledExecutorService that I am using to run a method updateIndex() every one minute. However, if changes to resources are made during the one minute between the last refresh and the next refresh, I would like to have updateIndex() called immediately, and then have the executor service resume it's normal schedule; i.e. next update will take place in one minute. However, I haven't seen anything in the documentation to suggest there is the capability to do this. Any ideas?
public static void updateIndex() {
Runnable runnable = () -> {
//Do your logic here
};
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.scheduleAtFixedRate(runnable, 0, 1, TimeUnit.MINUTES);
}
According to JavaDocs
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.
scheduleAtFixedRate() returns a ScheduledFuture which is a Future which has the cancel method you're looking for.
I'm currently trying to use a Timer to execute an action at set intervals.
I've taken a snippet from Stack Overflow, however it did not have an explanation, and I'm struggling to figure out what it's parameters mean.
Could someone please explain to me the parameters for the method?
It's namely the last 2 parameters, 5000, 5000 which I don't understand.
TimerTask damageInterval = new TimerTask() {
public void run() {
playerInfoPanel.health -= monsterDamage - playerInfoPanel.defenceLevel;
}
};
inflictDamage.schedule(damageInterval, 5000, 5000);
JavaDocs are your friend
public void schedule(TimerTask task,
long delay,
long period)
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.
In fixed-delay execution, each execution is scheduled relative to the
actual execution time of the previous execution. If an execution is
delayed for any reason (such as garbage collection or other background
activity), subsequent executions will be delayed as well. In the long
run, the frequency of execution will generally be slightly lower than
the reciprocal of the specified period (assuming the system clock
underlying Object.wait(long) is accurate).
Fixed-delay execution is appropriate for recurring activities that
require "smoothness." In other words, it is appropriate for activities
where it is more important to keep the frequency accurate in the short
run than in the long run. This includes most animation tasks, such as
blinking a cursor at regular intervals. It also includes tasks wherein
regular activity is performed in response to human input, such as
automatically repeating a character as long as a key is held down.
Parameters: task - task to be scheduled. delay - delay in milliseconds before task is to be executed. period - time in
milliseconds between successive task executions.
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.