Java Reference
In-Depth Information
construct a
ScheduledThreadPoolExecutor
through its constructor or through the
newScheduledThreadPool
factory.
A
Timer
creates only a single thread for executing timer tasks. If a timer task takes too long
to run, the timing accuracy of other
TimerTask
s can suffer. If a recurring
TimerTask
is
scheduled to run every 10 ms and another
Timer-Task
takes 40 ms to run, the recurring
task either (depending on whether it was scheduled at fixed rate or fixed delay) gets called
four times in rapid succession after the long-running task completes, or “misses” four invoc-
ations completely. Scheduled thread pools address this limitation by letting you provide mul-
tiple threads for executing deferred and periodic tasks.
Another problem with
Timer
is that it behaves poorly if a
TimerTask
throws an un-
checked exception. The
Timer
thread doesn't catch the exception, so an unchecked excep-
tion thrown from a
TimerTask
terminates the timer thread.
Timer
also doesn't resurrect
the thread in this situation; instead, it erroneously assumes the entire
Timer
was cancelled.
In this case,
TimerTask
s that are already scheduled but not yet executed are never run, and
new tasks cannot be scheduled. (This problem, called “thread leakage” is described in
Sec-
and, as confusion loves company, how the
Timer
shares its confusion with the next hapless
caller that tries to submit a
TimerTask
. You might expect the program to run for six
seconds and exit, but what actually happens is that it terminates after one second with an
IllegalStateException
whose message text is “Timer already cancelled”.
Sched-
uledThreadPoolExecutor
deals properly with ill-behaved tasks; there is little reason
to use
Timer
in Java 5.0 or later.
If you need to build your own scheduling service, you may still be able to take advantage of
the library by using a
DelayQueue
, a
BlockingQueue
implementation that provides the
scheduling functionality of
ScheduledThreadPoolExecutor
. A
DelayQueue
man-
ages a collection of
Delayed
objects. A
Delayed
has a delay time associated with it:
DelayQueue
lets you
take
an element only if its delay has expired. Objects are returned
from a
DelayQueue
ordered by the time associated with their delay.
6.3. Finding Exploitable Parallelism
The
Executor
framework makes it easy to specify an execution policy, but in order to use
an
Executor
, you have to be able to describe your task as a
Runnable
. In most server