ScheduledThreadPoolExecutorpublic class ScheduledThreadPoolExecutor extends ThreadPoolExecutor implements ScheduledExecutorServiceA {@link ThreadPoolExecutor} that can additionally schedule
commands to run after a given delay, or to execute
periodically. This class is preferable to {@link java.util.Timer}
when multiple worker threads are needed, or when the additional
flexibility or capabilities of {@link ThreadPoolExecutor} (which
this class extends) are required.
Delayed tasks execute no sooner than they are enabled, but
without any real-time guarantees about when, after they are
enabled, they will commence. Tasks scheduled for exactly the same
execution time are enabled in first-in-first-out (FIFO) order of
submission.
While this class inherits from {@link ThreadPoolExecutor}, a few
of the inherited tuning methods are not useful for it. In
particular, because it acts as a fixed-sized pool using
corePoolSize threads and an unbounded queue, adjustments
to maximumPoolSize have no useful effect.
Extension notes: This class overrides {@link
AbstractExecutorService} submit methods to generate
internal objects to control per-task delays and scheduling. To
preserve functionality, any further overrides of these methods in
subclasses must invoke superclass versions, which effectively
disables additional task customization. However, this class
provides alternative protected extension method
decorateTask (one version each for Runnable and
Callable) that can be used to customize the concrete task
types used to execute commands entered via execute,
submit, schedule, scheduleAtFixedRate,
and scheduleWithFixedDelay. By default, a
ScheduledThreadPoolExecutor uses a task type extending
{@link FutureTask}. However, this may be modified or replaced using
subclasses of the form:
public class CustomScheduledExecutor extends ScheduledThreadPoolExecutor {
static class CustomTask<V> implements RunnableScheduledFuture<V> { ... }
protected <V> RunnableScheduledFuture<V> decorateTask(
Runnable r, RunnableScheduledFuture<V> task) {
return new CustomTask<V>(r, task);
}
protected <V> RunnableScheduledFuture<V> decorateTask(
Callable<V> c, RunnableScheduledFuture<V> task) {
return new CustomTask<V>(c, task);
}
// ... add constructors, etc.
}
|
Fields Summary |
---|
private volatile boolean | continueExistingPeriodicTasksAfterShutdownFalse if should cancel/suppress periodic tasks on shutdown. | private volatile boolean | executeExistingDelayedTasksAfterShutdownFalse if should cancel non-periodic tasks on shutdown. | private static final AtomicLong | sequencerSequence number to break scheduling ties, and in turn to
guarantee FIFO order among tied entries. | private static final long | NANO_ORIGINBase of nanosecond timings, to avoid wrapping |
Constructors Summary |
---|
public ScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory, RejectedExecutionHandler handler)Creates a new ScheduledThreadPoolExecutor with the given
initial parameters.
super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
new DelayedWorkQueue(), threadFactory, handler);
| public ScheduledThreadPoolExecutor(int corePoolSize)Creates a new ScheduledThreadPoolExecutor with the given core
pool size.
super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
new DelayedWorkQueue());
| public ScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory)Creates a new ScheduledThreadPoolExecutor with the given
initial parameters.
super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
new DelayedWorkQueue(), threadFactory);
| public ScheduledThreadPoolExecutor(int corePoolSize, RejectedExecutionHandler handler)Creates a new ScheduledThreadPoolExecutor with the given
initial parameters.
super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
new DelayedWorkQueue(), handler);
|
Methods Summary |
---|
private void | cancelUnwantedTasks()Cancels and clears the queue of all tasks that should not be run
due to shutdown policy.
boolean keepDelayed = getExecuteExistingDelayedTasksAfterShutdownPolicy();
boolean keepPeriodic = getContinueExistingPeriodicTasksAfterShutdownPolicy();
if (!keepDelayed && !keepPeriodic)
super.getQueue().clear();
else if (keepDelayed || keepPeriodic) {
Object[] entries = super.getQueue().toArray();
for (int i = 0; i < entries.length; ++i) {
Object e = entries[i];
if (e instanceof RunnableScheduledFuture) {
RunnableScheduledFuture<?> t = (RunnableScheduledFuture<?>)e;
if (t.isPeriodic()? !keepPeriodic : !keepDelayed)
t.cancel(false);
}
}
entries = null;
purge();
}
| protected java.util.concurrent.RunnableScheduledFuture | decorateTask(java.lang.Runnable runnable, java.util.concurrent.RunnableScheduledFuture task)Modifies or replaces the task used to execute a runnable.
This method can be used to override the concrete
class used for managing internal tasks.
The default implementation simply returns the given task.
return task;
| protected java.util.concurrent.RunnableScheduledFuture | decorateTask(java.util.concurrent.Callable callable, java.util.concurrent.RunnableScheduledFuture task)Modifies or replaces the task used to execute a callable.
This method can be used to override the concrete
class used for managing internal tasks.
The default implementation simply returns the given task.
return task;
| private void | delayedExecute(java.lang.Runnable command)Specialized variant of ThreadPoolExecutor.execute for delayed tasks.
if (isShutdown()) {
reject(command);
return;
}
// Prestart a thread if necessary. We cannot prestart it
// running the task because the task (probably) shouldn't be
// run yet, so thread will just idle until delay elapses.
if (getPoolSize() < getCorePoolSize())
prestartCoreThread();
super.getQueue().add(command);
| public void | execute(java.lang.Runnable command)Executes command with zero required delay. This has effect
equivalent to schedule(command, 0, anyUnit). Note
that inspections of the queue and of the list returned by
shutdownNow will access the zero-delayed
{@link ScheduledFuture}, not the command itself.
if (command == null)
throw new NullPointerException();
schedule(command, 0, TimeUnit.NANOSECONDS);
| public boolean | getContinueExistingPeriodicTasksAfterShutdownPolicy()Gets the policy on whether to continue executing existing
periodic tasks even when this executor has been
shutdown. In this case, these tasks will only
terminate upon shutdownNow or after setting the policy
to false when already shutdown. This value is by
default false.
return continueExistingPeriodicTasksAfterShutdown;
| public boolean | getExecuteExistingDelayedTasksAfterShutdownPolicy()Gets the policy on whether to execute existing delayed
tasks even when this executor has been shutdown. In
this case, these tasks will only terminate upon
shutdownNow, or after setting the policy to
false when already shutdown. This value is by default
true.
return executeExistingDelayedTasksAfterShutdown;
| public java.util.concurrent.BlockingQueue | getQueue()Returns the task queue used by this executor. Each element of
this queue is a {@link ScheduledFuture}, including those
tasks submitted using execute which are for scheduling
purposes used as the basis of a zero-delay
ScheduledFuture. Iteration over this queue is
not guaranteed to traverse tasks in the order in
which they will execute.
return super.getQueue();
| final long | now()Returns nanosecond time offset by origin
return System.nanoTime() - NANO_ORIGIN;
| public boolean | remove(java.lang.Runnable task)
if (!(task instanceof RunnableScheduledFuture))
return false;
return getQueue().remove(task);
| public java.util.concurrent.ScheduledFuture | schedule(java.lang.Runnable command, long delay, java.util.concurrent.TimeUnit unit)
if (command == null || unit == null)
throw new NullPointerException();
long triggerTime = now() + unit.toNanos(delay);
RunnableScheduledFuture<?> t = decorateTask(command,
new ScheduledFutureTask<Boolean>(command, null, triggerTime));
delayedExecute(t);
return t;
| public java.util.concurrent.ScheduledFuture | schedule(java.util.concurrent.Callable callable, long delay, java.util.concurrent.TimeUnit unit)
if (callable == null || unit == null)
throw new NullPointerException();
if (delay < 0) delay = 0;
long triggerTime = now() + unit.toNanos(delay);
RunnableScheduledFuture<V> t = decorateTask(callable,
new ScheduledFutureTask<V>(callable, triggerTime));
delayedExecute(t);
return t;
| public java.util.concurrent.ScheduledFuture | scheduleAtFixedRate(java.lang.Runnable command, long initialDelay, long period, java.util.concurrent.TimeUnit unit)
if (command == null || unit == null)
throw new NullPointerException();
if (period <= 0)
throw new IllegalArgumentException();
if (initialDelay < 0) initialDelay = 0;
long triggerTime = now() + unit.toNanos(initialDelay);
RunnableScheduledFuture<?> t = decorateTask(command,
new ScheduledFutureTask<Object>(command,
null,
triggerTime,
unit.toNanos(period)));
delayedExecute(t);
return t;
| public java.util.concurrent.ScheduledFuture | scheduleWithFixedDelay(java.lang.Runnable command, long initialDelay, long delay, java.util.concurrent.TimeUnit unit)
if (command == null || unit == null)
throw new NullPointerException();
if (delay <= 0)
throw new IllegalArgumentException();
if (initialDelay < 0) initialDelay = 0;
long triggerTime = now() + unit.toNanos(initialDelay);
RunnableScheduledFuture<?> t = decorateTask(command,
new ScheduledFutureTask<Boolean>(command,
null,
triggerTime,
unit.toNanos(-delay)));
delayedExecute(t);
return t;
| public void | setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean value)Sets the policy on whether to continue executing existing periodic
tasks even when this executor has been shutdown. In
this case, these tasks will only terminate upon
shutdownNow, or after setting the policy to
false when already shutdown. This value is by default
false.
continueExistingPeriodicTasksAfterShutdown = value;
if (!value && isShutdown())
cancelUnwantedTasks();
| public void | setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean value)Sets the policy on whether to execute existing delayed
tasks even when this executor has been shutdown. In
this case, these tasks will only terminate upon
shutdownNow, or after setting the policy to
false when already shutdown. This value is by default
true.
executeExistingDelayedTasksAfterShutdown = value;
if (!value && isShutdown())
cancelUnwantedTasks();
| public void | shutdown()Initiates an orderly shutdown in which previously submitted
tasks are executed, but no new tasks will be accepted. If the
ExecuteExistingDelayedTasksAfterShutdownPolicy has
been set false, existing delayed tasks whose delays
have not yet elapsed are cancelled. And unless the
ContinueExistingPeriodicTasksAfterShutdownPolicy has
been set true, future executions of existing periodic
tasks will be cancelled.
cancelUnwantedTasks();
super.shutdown();
| public java.util.List | shutdownNow()Attempts to stop all actively executing tasks, halts the
processing of waiting tasks, and returns a list of the tasks
that were awaiting execution.
There are no guarantees beyond best-effort attempts to stop
processing actively executing tasks. This implementation
cancels tasks via {@link Thread#interrupt}, so any task that
fails to respond to interrupts may never terminate.
return super.shutdownNow();
| public java.util.concurrent.Future | submit(java.lang.Runnable task)
return schedule(task, 0, TimeUnit.NANOSECONDS);
| public java.util.concurrent.Future | submit(java.lang.Runnable task, T result)
return schedule(Executors.callable(task, result),
0, TimeUnit.NANOSECONDS);
| public java.util.concurrent.Future | submit(java.util.concurrent.Callable task)
return schedule(task, 0, TimeUnit.NANOSECONDS);
|
|