45 * when multiple worker threads are needed, or when the additional
46 * flexibility or capabilities of {@link ThreadPoolExecutor} (which
47 * this class extends) are required.
48 *
49 * <p>Delayed tasks execute no sooner than they are enabled, but
50 * without any real-time guarantees about when, after they are
51 * enabled, they will commence. Tasks scheduled for exactly the same
52 * execution time are enabled in first-in-first-out (FIFO) order of
53 * submission.
54 *
55 * <p>When a submitted task is cancelled before it is run, execution
56 * is suppressed. By default, such a cancelled task is not
57 * automatically removed from the work queue until its delay
58 * elapses. While this enables further inspection and monitoring, it
59 * may also cause unbounded retention of cancelled tasks. To avoid
60 * this, set {@link #setRemoveOnCancelPolicy} to {@code true}, which
61 * causes tasks to be immediately removed from the work queue at
62 * time of cancellation.
63 *
64 * <p>Successive executions of a task scheduled via
65 * <code>scheduleAtFixedRate</code> or
66 * <code>scheduleWithFixedDelay</code> do not overlap. While different
67 * executions may be performed by different threads, the effects of
68 * prior executions <a
69 * href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
70 * those of subsequent ones.
71 *
72 * <p>While this class inherits from {@link ThreadPoolExecutor}, a few
73 * of the inherited tuning methods are not useful for it. In
74 * particular, because it acts as a fixed-sized pool using
75 * {@code corePoolSize} threads and an unbounded queue, adjustments
76 * to {@code maximumPoolSize} have no useful effect. Additionally, it
77 * is almost never a good idea to set {@code corePoolSize} to zero or
78 * use {@code allowCoreThreadTimeOut} because this may leave the pool
79 * without threads to handle tasks once they become eligible to run.
80 *
81 * <p><b>Extension notes:</b> This class overrides the
82 * {@link ThreadPoolExecutor#execute execute} and
83 * {@link AbstractExecutorService#submit(Runnable) submit}
84 * methods to generate internal {@link ScheduledFuture} objects to
85 * control per-task delays and scheduling. To preserve
86 * functionality, any further overrides of these methods in
343 void reExecutePeriodic(RunnableScheduledFuture<?> task) {
344 if (canRunInCurrentRunState(true)) {
345 super.getQueue().add(task);
346 if (!canRunInCurrentRunState(true) && remove(task))
347 task.cancel(false);
348 else
349 prestartCoreThread();
350 }
351 }
352
353 /**
354 * Cancels and clears the queue of all tasks that should not be run
355 * due to shutdown policy. Invoked within super.shutdown.
356 */
357 @Override void onShutdown() {
358 BlockingQueue<Runnable> q = super.getQueue();
359 boolean keepDelayed =
360 getExecuteExistingDelayedTasksAfterShutdownPolicy();
361 boolean keepPeriodic =
362 getContinueExistingPeriodicTasksAfterShutdownPolicy();
363 if (!keepDelayed && !keepPeriodic)
364 q.clear();
365 else {
366 // Traverse snapshot to avoid iterator exceptions
367 for (Object e : q.toArray()) {
368 if (e instanceof RunnableScheduledFuture) {
369 RunnableScheduledFuture<?> t =
370 (RunnableScheduledFuture<?>)e;
371 if ((t.isPeriodic() ? !keepPeriodic : !keepDelayed) ||
372 t.isCancelled()) { // also remove if already cancelled
373 if (q.remove(t))
374 t.cancel(false);
375 }
376 }
377 }
378 }
379 tryTerminate();
380 }
381
382 /**
383 * Modifies or replaces the task used to execute a runnable.
384 * This method can be used to override the concrete
|
45 * when multiple worker threads are needed, or when the additional
46 * flexibility or capabilities of {@link ThreadPoolExecutor} (which
47 * this class extends) are required.
48 *
49 * <p>Delayed tasks execute no sooner than they are enabled, but
50 * without any real-time guarantees about when, after they are
51 * enabled, they will commence. Tasks scheduled for exactly the same
52 * execution time are enabled in first-in-first-out (FIFO) order of
53 * submission.
54 *
55 * <p>When a submitted task is cancelled before it is run, execution
56 * is suppressed. By default, such a cancelled task is not
57 * automatically removed from the work queue until its delay
58 * elapses. While this enables further inspection and monitoring, it
59 * may also cause unbounded retention of cancelled tasks. To avoid
60 * this, set {@link #setRemoveOnCancelPolicy} to {@code true}, which
61 * causes tasks to be immediately removed from the work queue at
62 * time of cancellation.
63 *
64 * <p>Successive executions of a task scheduled via
65 * {@code scheduleAtFixedRate} or
66 * {@code scheduleWithFixedDelay} do not overlap. While different
67 * executions may be performed by different threads, the effects of
68 * prior executions <a
69 * href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
70 * those of subsequent ones.
71 *
72 * <p>While this class inherits from {@link ThreadPoolExecutor}, a few
73 * of the inherited tuning methods are not useful for it. In
74 * particular, because it acts as a fixed-sized pool using
75 * {@code corePoolSize} threads and an unbounded queue, adjustments
76 * to {@code maximumPoolSize} have no useful effect. Additionally, it
77 * is almost never a good idea to set {@code corePoolSize} to zero or
78 * use {@code allowCoreThreadTimeOut} because this may leave the pool
79 * without threads to handle tasks once they become eligible to run.
80 *
81 * <p><b>Extension notes:</b> This class overrides the
82 * {@link ThreadPoolExecutor#execute execute} and
83 * {@link AbstractExecutorService#submit(Runnable) submit}
84 * methods to generate internal {@link ScheduledFuture} objects to
85 * control per-task delays and scheduling. To preserve
86 * functionality, any further overrides of these methods in
343 void reExecutePeriodic(RunnableScheduledFuture<?> task) {
344 if (canRunInCurrentRunState(true)) {
345 super.getQueue().add(task);
346 if (!canRunInCurrentRunState(true) && remove(task))
347 task.cancel(false);
348 else
349 prestartCoreThread();
350 }
351 }
352
353 /**
354 * Cancels and clears the queue of all tasks that should not be run
355 * due to shutdown policy. Invoked within super.shutdown.
356 */
357 @Override void onShutdown() {
358 BlockingQueue<Runnable> q = super.getQueue();
359 boolean keepDelayed =
360 getExecuteExistingDelayedTasksAfterShutdownPolicy();
361 boolean keepPeriodic =
362 getContinueExistingPeriodicTasksAfterShutdownPolicy();
363 if (!keepDelayed && !keepPeriodic) {
364 for (Object e : q.toArray())
365 if (e instanceof RunnableScheduledFuture<?>)
366 ((RunnableScheduledFuture<?>) e).cancel(false);
367 q.clear();
368 }
369 else {
370 // Traverse snapshot to avoid iterator exceptions
371 for (Object e : q.toArray()) {
372 if (e instanceof RunnableScheduledFuture) {
373 RunnableScheduledFuture<?> t =
374 (RunnableScheduledFuture<?>)e;
375 if ((t.isPeriodic() ? !keepPeriodic : !keepDelayed) ||
376 t.isCancelled()) { // also remove if already cancelled
377 if (q.remove(t))
378 t.cancel(false);
379 }
380 }
381 }
382 }
383 tryTerminate();
384 }
385
386 /**
387 * Modifies or replaces the task used to execute a runnable.
388 * This method can be used to override the concrete
|