ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ScheduledThreadPoolExecutor.java
(Generate patch)

Comparing jsr166/src/main/java/util/concurrent/ScheduledThreadPoolExecutor.java (file contents):
Revision 1.38 by jsr166, Sun Sep 3 06:04:35 2006 UTC vs.
Revision 1.39 by jsr166, Tue Jan 30 03:43:07 2007 UTC

# Line 25 | Line 25 | import java.util.*;
25   * <p>While this class inherits from {@link ThreadPoolExecutor}, a few
26   * of the inherited tuning methods are not useful for it. In
27   * particular, because it acts as a fixed-sized pool using
28 < * <tt>corePoolSize</tt> threads and an unbounded queue, adjustments
29 < * to <tt>maximumPoolSize</tt> have no useful effect. Additionally, it
30 < * is almost never a good idea to set <tt>corePoolSize</tt> to zero or
31 < * use <tt>allowCoreThreadTimeOut</tt> because this may leave the pool
28 > * {@code corePoolSize} threads and an unbounded queue, adjustments
29 > * to {@code maximumPoolSize} have no useful effect. Additionally, it
30 > * is almost never a good idea to set {@code corePoolSize} to zero or
31 > * use {@code allowCoreThreadTimeOut} because this may leave the pool
32   * without threads to handle tasks once they become eligible to run.
33   *
34 < * <p><b>Extension notes:</b> This class overrides {@link
35 < * AbstractExecutorService} <tt>submit</tt> methods to generate
36 < * internal objects to control per-task delays and scheduling. To
37 < * preserve functionality, any further overrides of these methods in
34 > * <p><b>Extension notes:</b> This class overrides the
35 > * {@link ThreadPoolExecutor#execute execute} and
36 > * {@link AbstractExecutorService#submit(Runnable) submit}
37 > * methods to generate internal {@link ScheduledFuture} objects to
38 > * control per-task delays and scheduling.  To preserve
39 > * functionality, any further overrides of these methods in
40   * subclasses must invoke superclass versions, which effectively
41 < * disables additional task customization. However, this class
41 > * disables additional task customization.  However, this class
42   * provides alternative protected extension method
43 < * <tt>decorateTask</tt> (one version each for <tt>Runnable</tt> and
44 < * <tt>Callable</tt>) that can be used to customize the concrete task
45 < * types used to execute commands entered via <tt>execute</tt>,
46 < * <tt>submit</tt>, <tt>schedule</tt>, <tt>scheduleAtFixedRate</tt>,
47 < * and <tt>scheduleWithFixedDelay</tt>.  By default, a
48 < * <tt>ScheduledThreadPoolExecutor</tt> uses a task type extending
43 > * {@code decorateTask} (one version each for {@code Runnable} and
44 > * {@code Callable}) that can be used to customize the concrete task
45 > * types used to execute commands entered via {@code execute},
46 > * {@code submit}, {@code schedule}, {@code scheduleAtFixedRate},
47 > * and {@code scheduleWithFixedDelay}.  By default, a
48 > * {@code ScheduledThreadPoolExecutor} uses a task type extending
49   * {@link FutureTask}. However, this may be modified or replaced using
50   * subclasses of the form:
51   *
52 < * <pre>
52 > *  <pre> {@code
53   * public class CustomScheduledExecutor extends ScheduledThreadPoolExecutor {
54   *
55 < *   static class CustomTask&lt;V&gt; implements RunnableScheduledFuture&lt;V&gt; { ... }
55 > *   static class CustomTask<V> implements RunnableScheduledFuture<V> { ... }
56   *
57 < *   protected &lt;V&gt; RunnableScheduledFuture&lt;V&gt; decorateTask(
58 < *                Runnable r, RunnableScheduledFuture&lt;V&gt; task) {
59 < *       return new CustomTask&lt;V&gt;(r, task);
57 > *   protected <V> RunnableScheduledFuture<V> decorateTask(
58 > *                Runnable r, RunnableScheduledFuture<V> task) {
59 > *       return new CustomTask<V>(r, task);
60   *   }
61   *
62 < *   protected &lt;V&gt; RunnableScheduledFuture&lt;V&gt; decorateTask(
63 < *                Callable&lt;V&gt; c, RunnableScheduledFuture&lt;V&gt; task) {
64 < *       return new CustomTask&lt;V&gt;(c, task);
62 > *   protected <V> RunnableScheduledFuture<V> decorateTask(
63 > *                Callable<V> c, RunnableScheduledFuture<V> task) {
64 > *       return new CustomTask<V>(c, task);
65   *   }
66   *   // ... add constructors, etc.
67 < * }
68 < * </pre>
67 > * }}</pre>
68 > *
69   * @since 1.5
70   * @author Doug Lea
71   */
# Line 124 | Line 126 | public class ScheduledThreadPoolExecutor
126       */
127      private static final AtomicLong sequencer = new AtomicLong(0);
128  
127    /** Base of nanosecond timings, to avoid wrapping */
128    private static final long NANO_ORIGIN = System.nanoTime();
129
129      /**
130 <     * Returns nanosecond time offset by origin
130 >     * Returns current nanosecond time.
131       */
132      final long now() {
133 <        return System.nanoTime() - NANO_ORIGIN;
133 >        return System.nanoTime();
134      }
135  
136      private class ScheduledFutureTask<V>
# Line 214 | Line 213 | public class ScheduledThreadPoolExecutor
213          }
214  
215          /**
216 <         * Sets the next time to run for a periodic task
216 >         * Sets the next time to run for a periodic task.
217           */
218          private void setNextRunTime() {
219              long p = period;
# Line 242 | Line 241 | public class ScheduledThreadPoolExecutor
241  
242      /**
243       * Returns true if can run a task given current run state
244 <     * and run-after-shutdown parameters
244 >     * and run-after-shutdown parameters.
245 >     *
246       * @param periodic true if this task periodic, false if delayed
247       */
248      boolean canRunInCurrentRunState(boolean periodic) {
# Line 258 | Line 258 | public class ScheduledThreadPoolExecutor
258       * prestart the thread to run the task because the task (probably)
259       * shouldn't be run yet,) If the pool is shut down while the task
260       * is being added, cancel and remove it if required by state and
261 <     * run-after-shutdown parameters
261 >     * run-after-shutdown parameters.
262 >     *
263       * @param task the task
264       */
265      private void delayedExecute(RunnableScheduledFuture<?> task) {
# Line 270 | Line 271 | public class ScheduledThreadPoolExecutor
271                  !canRunInCurrentRunState(task.isPeriodic()) &&
272                  remove(task))
273                  task.cancel(false);
274 <            prestartCoreThread();
274 >            else
275 >                prestartCoreThread();
276          }
277      }
278  
279      /**
280 <     * Requeues a periodic task unless current run state precludes
281 <     * it. Same idea as delayedExecute except drops task rather than
282 <     * rejecting.
280 >     * Requeues a periodic task unless current run state precludes it.
281 >     * Same idea as delayedExecute except drops task rather than rejecting.
282 >     *
283       * @param task the task
284       */
285      void reExecutePeriodic(RunnableScheduledFuture<?> task) {
# Line 285 | Line 287 | public class ScheduledThreadPoolExecutor
287              super.getQueue().add(task);
288              if (!canRunInCurrentRunState(true) && remove(task))
289                  task.cancel(false);
290 <            prestartCoreThread();
290 >            else
291 >                prestartCoreThread();
292          }
293      }
294  
295      /**
296       * Cancels and clears the queue of all tasks that should not be run
297 <     * due to shutdown policy. Invoked within super.shutdown.
297 >     * due to shutdown policy.  Invoked within super.shutdown.
298       */
299      @Override void onShutdown() {
300          BlockingQueue<Runnable> q = super.getQueue();
# Line 303 | Line 306 | public class ScheduledThreadPoolExecutor
306              q.clear();
307          else {
308              // Traverse snapshot to avoid iterator exceptions
309 <            Object[] entries = q.toArray();
307 <            for (int i = 0; i < entries.length; ++i) {
308 <                Object e = entries[i];
309 >            for (Object e : q.toArray()) {
310                  if (e instanceof RunnableScheduledFuture) {
311                      RunnableScheduledFuture<?> t =
312                          (RunnableScheduledFuture<?>)e;
# Line 317 | Line 318 | public class ScheduledThreadPoolExecutor
318                  }
319              }
320          }
321 +        tryTerminate();
322      }
323  
324      /**
# Line 352 | Line 354 | public class ScheduledThreadPoolExecutor
354      }
355  
356      /**
357 <     * Creates a new ScheduledThreadPoolExecutor with the given core
358 <     * pool size.
357 >     * Creates a new {@code ScheduledThreadPoolExecutor} with the
358 >     * given core pool size.
359       *
360 <     * @param corePoolSize the number of threads to keep in the pool,
361 <     * even if they are idle, unless allowCoreThreadTimeOut is set
362 <     * @throws IllegalArgumentException if <tt>corePoolSize &lt; 0</tt>
360 >     * @param corePoolSize the number of threads to keep in the pool, even
361 >     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
362 >     * @throws IllegalArgumentException if {@code corePoolSize < 0}
363       */
364      public ScheduledThreadPoolExecutor(int corePoolSize) {
365          super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
# Line 365 | Line 367 | public class ScheduledThreadPoolExecutor
367      }
368  
369      /**
370 <     * Creates a new ScheduledThreadPoolExecutor with the given
371 <     * initial parameters.
370 >     * Creates a new {@code ScheduledThreadPoolExecutor} with the
371 >     * given initial parameters.
372       *
373 <     * @param corePoolSize the number of threads to keep in the pool,
374 <     * even if they are idle, unless allowCoreThreadTimeOut is set
373 >     * @param corePoolSize the number of threads to keep in the pool, even
374 >     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
375       * @param threadFactory the factory to use when the executor
376 <     * creates a new thread
377 <     * @throws IllegalArgumentException if <tt>corePoolSize &lt; 0</tt>
378 <     * @throws NullPointerException if threadFactory is null
376 >     *        creates a new thread
377 >     * @throws IllegalArgumentException if {@code corePoolSize < 0}
378 >     * @throws NullPointerException if {@code threadFactory} is null
379       */
380      public ScheduledThreadPoolExecutor(int corePoolSize,
381                               ThreadFactory threadFactory) {
# Line 385 | Line 387 | public class ScheduledThreadPoolExecutor
387       * Creates a new ScheduledThreadPoolExecutor with the given
388       * initial parameters.
389       *
390 <     * @param corePoolSize the number of threads to keep in the pool,
391 <     * even if they are idle, unless allowCoreThreadTimeOut is set
390 >     * @param corePoolSize the number of threads to keep in the pool, even
391 >     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
392       * @param handler the handler to use when execution is blocked
393 <     * because the thread bounds and queue capacities are reached
394 <     * @throws IllegalArgumentException if <tt>corePoolSize &lt; 0</tt>
395 <     * @throws NullPointerException if handler is null
393 >     *        because the thread bounds and queue capacities are reached
394 >     * @throws IllegalArgumentException if {@code corePoolSize < 0}
395 >     * @throws NullPointerException if {@code handler} is null
396       */
397      public ScheduledThreadPoolExecutor(int corePoolSize,
398                                RejectedExecutionHandler handler) {
# Line 402 | Line 404 | public class ScheduledThreadPoolExecutor
404       * Creates a new ScheduledThreadPoolExecutor with the given
405       * initial parameters.
406       *
407 <     * @param corePoolSize the number of threads to keep in the pool,
408 <     * even if they are idle, unless allowCoreThreadTimeOut is set
407 >     * @param corePoolSize the number of threads to keep in the pool, even
408 >     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
409       * @param threadFactory the factory to use when the executor
410 <     * creates a new thread
410 >     *        creates a new thread
411       * @param handler the handler to use when execution is blocked
412 <     * because the thread bounds and queue capacities are reached.
413 <     * @throws IllegalArgumentException if <tt>corePoolSize &lt; 0</tt>
414 <     * @throws NullPointerException if threadFactory or handler is null
412 >     *        because the thread bounds and queue capacities are reached
413 >     * @throws IllegalArgumentException if {@code corePoolSize < 0}
414 >     * @throws NullPointerException if {@code threadFactory} or
415 >     *         {@code handler} is null
416       */
417      public ScheduledThreadPoolExecutor(int corePoolSize,
418                                ThreadFactory threadFactory,
# Line 501 | Line 504 | public class ScheduledThreadPoolExecutor
504      }
505  
506      /**
507 <     * Executes command with zero required delay. This has effect
508 <     * equivalent to <tt>schedule(command, 0, anyUnit)</tt>.  Note
509 <     * that inspections of the queue and of the list returned by
510 <     * <tt>shutdownNow</tt> will access the zero-delayed
511 <     * {@link ScheduledFuture}, not the <tt>command</tt> itself.
507 >     * Executes {@code command} with zero required delay.
508 >     * This has effect equivalent to
509 >     * {@link #schedule(Runnable,long,TimeUnit) schedule(command, 0, anyUnit)}.
510 >     * Note that inspections of the queue and of the list returned by
511 >     * {@code shutdownNow} will access the zero-delayed
512 >     * {@link ScheduledFuture}, not the {@code command} itself.
513 >     *
514 >     * <p>A consequence of the use of {@code ScheduledFuture} objects is
515 >     * that {@link ThreadPoolExecutor#afterExecute afterExecute} is always
516 >     * called with a null second {@code Throwable} argument, even if the
517 >     * {@code command} terminated abruptly.  Instead, the {@code Throwable}
518 >     * thrown by such a task can be obtained via {@link Future#get}.
519       *
510     * @param command the task to execute
520       * @throws RejectedExecutionException at discretion of
521 <     * <tt>RejectedExecutionHandler</tt>, if task cannot be accepted
522 <     * for execution because the executor has been shut down.
523 <     * @throws NullPointerException if command is null
521 >     *         {@code RejectedExecutionHandler}, if the task
522 >     *         cannot be accepted for execution because the
523 >     *         executor has been shut down
524 >     * @throws NullPointerException {@inheritDoc}
525       */
526      public void execute(Runnable command) {
517        if (command == null)
518            throw new NullPointerException();
527          schedule(command, 0, TimeUnit.NANOSECONDS);
528      }
529  
# Line 548 | Line 556 | public class ScheduledThreadPoolExecutor
556  
557      /**
558       * Sets the policy on whether to continue executing existing
559 <     * periodic tasks even when this executor has been
560 <     * <tt>shutdown</tt>. In this case, these tasks will only
561 <     * terminate upon <tt>shutdownNow</tt>, or after setting the
562 <     * policy to <tt>false</tt> when already shutdown. This value is
563 <     * by default false.
559 >     * periodic tasks even when this executor has been {@code shutdown}.
560 >     * In this case, these tasks will only terminate upon
561 >     * {@code shutdownNow} or after setting the policy to
562 >     * {@code false} when already shutdown.
563 >     * This value is by default {@code false}.
564       *
565 <     * @param value if true, continue after shutdown, else don't.
565 >     * @param value if {@code true}, continue after shutdown, else don't.
566       * @see #getContinueExistingPeriodicTasksAfterShutdownPolicy
567       */
568      public void setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean value) {
569          continueExistingPeriodicTasksAfterShutdown = value;
570 <        if (!value && isShutdown()) {
570 >        if (!value && isShutdown())
571              onShutdown();
564            tryTerminate();
565        }
572      }
573  
574      /**
575       * Gets the policy on whether to continue executing existing
576 <     * periodic tasks even when this executor has been
577 <     * <tt>shutdown</tt>. In this case, these tasks will only
578 <     * terminate upon <tt>shutdownNow</tt> or after setting the policy
579 <     * to <tt>false</tt> when already shutdown. This value is by
580 <     * default false.
576 >     * periodic tasks even when this executor has been {@code shutdown}.
577 >     * In this case, these tasks will only terminate upon
578 >     * {@code shutdownNow} or after setting the policy to
579 >     * {@code false} when already shutdown.
580 >     * This value is by default {@code false}.
581       *
582 <     * @return true if will continue after shutdown
582 >     * @return {@code true} if will continue after shutdown
583       * @see #setContinueExistingPeriodicTasksAfterShutdownPolicy
584       */
585      public boolean getContinueExistingPeriodicTasksAfterShutdownPolicy() {
# Line 582 | Line 588 | public class ScheduledThreadPoolExecutor
588  
589      /**
590       * Sets the policy on whether to execute existing delayed
591 <     * tasks even when this executor has been <tt>shutdown</tt>. In
592 <     * this case, these tasks will only terminate upon
593 <     * <tt>shutdownNow</tt>, or after setting the policy to
594 <     * <tt>false</tt> when already shutdown. This value is by default
595 <     * true.
591 >     * tasks even when this executor has been {@code shutdown}.
592 >     * In this case, these tasks will only terminate upon
593 >     * {@code shutdownNow}, or after setting the policy to
594 >     * {@code false} when already shutdown.
595 >     * This value is by default {@code true}.
596       *
597 <     * @param value if true, execute after shutdown, else don't.
597 >     * @param value if {@code true}, execute after shutdown, else don't.
598       * @see #getExecuteExistingDelayedTasksAfterShutdownPolicy
599       */
600      public void setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean value) {
601          executeExistingDelayedTasksAfterShutdown = value;
602 <        if (!value && isShutdown()) {
602 >        if (!value && isShutdown())
603              onShutdown();
598            tryTerminate();
599        }
604      }
605  
606      /**
607       * Gets the policy on whether to execute existing delayed
608 <     * tasks even when this executor has been <tt>shutdown</tt>. In
609 <     * this case, these tasks will only terminate upon
610 <     * <tt>shutdownNow</tt>, or after setting the policy to
611 <     * <tt>false</tt> when already shutdown. This value is by default
612 <     * true.
608 >     * tasks even when this executor has been {@code shutdown}.
609 >     * In this case, these tasks will only terminate upon
610 >     * {@code shutdownNow}, or after setting the policy to
611 >     * {@code false} when already shutdown.
612 >     * This value is by default {@code true}.
613       *
614 <     * @return true if will execute after shutdown
614 >     * @return {@code true} if will execute after shutdown
615       * @see #setExecuteExistingDelayedTasksAfterShutdownPolicy
616       */
617      public boolean getExecuteExistingDelayedTasksAfterShutdownPolicy() {
# Line 616 | Line 620 | public class ScheduledThreadPoolExecutor
620  
621      /**
622       * Initiates an orderly shutdown in which previously submitted
623 <     * tasks are executed, but no new tasks will be accepted. If the
624 <     * <tt>ExecuteExistingDelayedTasksAfterShutdownPolicy</tt> has
625 <     * been set <tt>false</tt>, existing delayed tasks whose delays
626 <     * have not yet elapsed are cancelled. And unless the
627 <     * <tt>ContinueExistingPeriodicTasksAfterShutdownPolicy</tt> has
628 <     * been set <tt>true</tt>, future executions of existing periodic
623 >     * tasks are executed, but no new tasks will be accepted.  If the
624 >     * {@code ExecuteExistingDelayedTasksAfterShutdownPolicy} has
625 >     * been set {@code false}, existing delayed tasks whose delays
626 >     * have not yet elapsed are cancelled.  And unless the
627 >     * {@code ContinueExistingPeriodicTasksAfterShutdownPolicy} has
628 >     * been set {@code true}, future executions of existing periodic
629       * tasks will be cancelled.
630 +     *
631 +     * @throws SecurityException {@inheritDoc}
632       */
633      public void shutdown() {
634          super.shutdown();
# Line 638 | Line 644 | public class ScheduledThreadPoolExecutor
644       * cancels tasks via {@link Thread#interrupt}, so any task that
645       * fails to respond to interrupts may never terminate.
646       *
647 <     * @return list of tasks that never commenced execution.  Each
648 <     * element of this list is a {@link ScheduledFuture},
649 <     * including those tasks submitted using <tt>execute</tt>, which
650 <     * are for scheduling purposes used as the basis of a zero-delay
651 <     * <tt>ScheduledFuture</tt>.
647 >     * @return list of tasks that never commenced execution.
648 >     *         Each element of this list is a {@link ScheduledFuture},
649 >     *         including those tasks submitted using {@code execute},
650 >     *         which are for scheduling purposes used as the basis of a
651 >     *         zero-delay {@code ScheduledFuture}.
652       * @throws SecurityException {@inheritDoc}
653       */
654      public List<Runnable> shutdownNow() {
# Line 652 | Line 658 | public class ScheduledThreadPoolExecutor
658      /**
659       * Returns the task queue used by this executor.  Each element of
660       * this queue is a {@link ScheduledFuture}, including those
661 <     * tasks submitted using <tt>execute</tt> which are for scheduling
661 >     * tasks submitted using {@code execute} which are for scheduling
662       * purposes used as the basis of a zero-delay
663 <     * <tt>ScheduledFuture</tt>. Iteration over this queue is
663 >     * {@code ScheduledFuture}.  Iteration over this queue is
664       * <em>not</em> guaranteed to traverse tasks in the order in
665       * which they will execute.
666       *

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines