I have code where I schedule a task using java.util.timer
. I was looking around and saw ExecutorService
can do the same. So this question here, have you used Timer and ExecutorService
to schedule tasks, what is the benefit of one using over another?
Also wanted to check if anyone had used the Timer
class and ran into any issues which the ExecutorService
solved for them.
Here's some more good practices around Timer use:
http://tech.puredanger.com/2008/09/22/timer-rules/
In general, I'd use Timer for quick and dirty stuff and Executor for more robust usage.
From Oracle documentation page on ScheduledThreadPoolExecutor
ExecutorService/ThreadPoolExecutor
orScheduledThreadPoolExecutor
is obvious choice when you have multiple worker threads.Pros of
ExecutorService
overTimer
Timer
can't take advantage of available CPU cores unlikeExecutorService
especially with multiple tasks using flavours ofExecutorService
like ForkJoinPoolExecutorService
provides collaborative API if you need coordination between multiple tasks. Assume that you have to submit N number of worker tasks and wait for completion of all of them. You can easily achieve it with invokeAll API. If you want to achieve the same with multipleTimer
tasks, it would be not simple.ThreadPoolExecutor provides better API for management of Thread life cycle.
Few advantages:
a. You can create/manage/control life cycle of Threads & optimize thread creation cost overheads
b. You can control processing of tasks ( Work Stealing, ForkJoinPool, invokeAll) etc.
c. You can monitor the progress and health of threads
d. Provides better exception handling mechanism
My reason for sometimes preferring Timer over Executors.newSingleThreadScheduledExecutor() is that I get much cleaner code when I need the timer to execute on daemon threads.
compare
with
I do this when I don't need the robustness of an executorservice.
ExecutorService is newer and more general. A timer is just a thread that periodically runs stuff you have scheduled for it.
An ExecutorService may be a thread pool, or even spread out across other systems in a cluster and do things like one-off batch execution, etc...
Just look at what each offers to decide.
According to Java Concurrency in Practice:
Timer
can be sensitive to changes in the system clock,ScheduledThreadPoolExecutor
isn't.Timer
has only one execution thread, so long-running task can delay other tasks.ScheduledThreadPoolExecutor
can be configured with any number of threads. Furthermore, you have full control over created threads, if you want (by providingThreadFactory
).TimerTask
kill that one thread, thus makingTimer
dead :-( ... i.e. scheduled tasks will not run anymore.ScheduledThreadExecutor
not only catches runtime exceptions, but it lets you handle them if you want (by overridingafterExecute
method fromThreadPoolExecutor
). Task which threw exception will be canceled, but other tasks will continue to run.If you can use
ScheduledThreadExecutor
instead ofTimer
, do so.One more thing... while
ScheduledThreadExecutor
isn't available in Java 1.4 library, there is a Backport of JSR 166 (java.util.concurrent
) to Java 1.2, 1.3, 1.4, which has theScheduledThreadExecutor
class.If it's available to you, then it's difficult to think of a reason not to use the Java 5 executor framework. Calling:
will give you a
ScheduledExecutorService
with similar functionality toTimer
(i.e. it will be single-threaded) but whose access may be slightly more scalable (under the hood, it uses concurrent structures rather than complete synchronization as with theTimer
class). Using aScheduledExecutorService
also gives you advantages such as:newScheduledThreadPoolExecutor()
or theScheduledThreadPoolExecutor
class)About the only reasons for sticking to
Timer
I can think of are: