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.