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

Comparing jsr166/src/jdk7/java/util/concurrent/ScheduledThreadPoolExecutor.java (file contents):
Revision 1.6 by jsr166, Fri Apr 11 21:15:44 2014 UTC vs.
Revision 1.7 by jsr166, Fri Apr 11 21:28:45 2014 UTC

# Line 6 | Line 6
6  
7   package java.util.concurrent;
8   import static java.util.concurrent.TimeUnit.NANOSECONDS;
9 + import static java.util.concurrent.TimeUnit.MILLISECONDS;
10   import java.util.concurrent.atomic.AtomicLong;
11   import java.util.concurrent.locks.Condition;
12   import java.util.concurrent.locks.ReentrantLock;
# Line 13 | Line 14 | import java.util.*;
14  
15   /**
16   * A {@link ThreadPoolExecutor} that can additionally schedule
17 < * commands to run after a given delay, or to execute
18 < * periodically. This class is preferable to {@link java.util.Timer}
19 < * when multiple worker threads are needed, or when the additional
20 < * flexibility or capabilities of {@link ThreadPoolExecutor} (which
21 < * this class extends) are required.
17 > * commands to run after a given delay, or to execute periodically.
18 > * This class is preferable to {@link java.util.Timer} when multiple
19 > * worker threads are needed, or when the additional flexibility or
20 > * capabilities of {@link ThreadPoolExecutor} (which this class
21 > * extends) are required.
22   *
23   * <p>Delayed tasks execute no sooner than they are enabled, but
24   * without any real-time guarantees about when, after they are
# Line 26 | Line 27 | import java.util.*;
27   * submission.
28   *
29   * <p>When a submitted task is cancelled before it is run, execution
30 < * is suppressed. By default, such a cancelled task is not
31 < * automatically removed from the work queue until its delay
32 < * elapses. While this enables further inspection and monitoring, it
33 < * may also cause unbounded retention of cancelled tasks. To avoid
34 < * this, set {@link #setRemoveOnCancelPolicy} to {@code true}, which
35 < * causes tasks to be immediately removed from the work queue at
35 < * time of cancellation.
30 > * is suppressed.  By default, such a cancelled task is not
31 > * automatically removed from the work queue until its delay elapses.
32 > * While this enables further inspection and monitoring, it may also
33 > * cause unbounded retention of cancelled tasks.  To avoid this, use
34 > * {@link #setRemoveOnCancelPolicy} to cause tasks to be immediately
35 > * removed from the work queue at time of cancellation.
36   *
37 < * <p>Successive executions of a task scheduled via
38 < * {@code scheduleAtFixedRate} or
39 < * {@code scheduleWithFixedDelay} do not overlap. While different
37 > * <p>Successive executions of a periodic task scheduled via
38 > * {@link #scheduleAtFixedRate} or
39 > * {@link #scheduleWithFixedDelay} do not overlap. While different
40   * executions may be performed by different threads, the effects of
41   * prior executions <a
42   * href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
# Line 131 | Line 131 | public class ScheduledThreadPoolExecutor
131      private volatile boolean executeExistingDelayedTasksAfterShutdown = true;
132  
133      /**
134 <     * True if ScheduledFutureTask.cancel should remove from queue
134 >     * True if ScheduledFutureTask.cancel should remove from queue.
135       */
136      private volatile boolean removeOnCancel = false;
137  
# Line 158 | Line 158 | public class ScheduledThreadPoolExecutor
158          private long time;
159  
160          /**
161 <         * Period in nanoseconds for repeating tasks.  A positive
162 <         * value indicates fixed-rate execution.  A negative value
163 <         * indicates fixed-delay execution.  A value of 0 indicates a
164 <         * non-repeating task.
161 >         * Period in nanoseconds for repeating tasks.
162 >         * A positive value indicates fixed-rate execution.
163 >         * A negative value indicates fixed-delay execution.
164 >         * A value of 0 indicates a non-repeating (one-shot) task.
165           */
166          private final long period;
167  
# Line 176 | Line 176 | public class ScheduledThreadPoolExecutor
176          /**
177           * Creates a one-shot action with given nanoTime-based trigger time.
178           */
179 <        ScheduledFutureTask(Runnable r, V result, long ns) {
179 >        ScheduledFutureTask(Runnable r, V result, long triggerTime) {
180              super(r, result);
181 <            this.time = ns;
181 >            this.time = triggerTime;
182              this.period = 0;
183              this.sequenceNumber = sequencer.getAndIncrement();
184          }
185  
186          /**
187 <         * Creates a periodic action with given nano time and period.
187 >         * Creates a periodic action with given nanoTime-based initial
188 >         * trigger time and period.
189           */
190 <        ScheduledFutureTask(Runnable r, V result, long ns, long period) {
190 >        ScheduledFutureTask(Runnable r, V result, long triggerTime,
191 >                            long period) {
192              super(r, result);
193 <            this.time = ns;
193 >            this.time = triggerTime;
194              this.period = period;
195              this.sequenceNumber = sequencer.getAndIncrement();
196          }
# Line 196 | Line 198 | public class ScheduledThreadPoolExecutor
198          /**
199           * Creates a one-shot action with given nanoTime-based trigger time.
200           */
201 <        ScheduledFutureTask(Callable<V> callable, long ns) {
201 >        ScheduledFutureTask(Callable<V> callable, long triggerTime) {
202              super(callable);
203 <            this.time = ns;
203 >            this.time = triggerTime;
204              this.period = 0;
205              this.sequenceNumber = sequencer.getAndIncrement();
206          }
# Line 390 | Line 392 | public class ScheduledThreadPoolExecutor
392      }
393  
394      /**
395 +     * The default keep-alive time for pool threads.
396 +     *
397 +     * Normally, this value is unused because all pool threads will be
398 +     * core threads, but if a user creates a pool with a corePoolSize
399 +     * of zero (against our advice), we keep a thread alive as long as
400 +     * there are queued tasks.  If the keep alive time is zero (the
401 +     * historic value), we end up hot-spinning in getTask, wasting a
402 +     * CPU.  But on the other hand, if we set the value too high, and
403 +     * users create a one-shot pool which they don't cleanly shutdown,
404 +     * the pool's non-daemon threads will prevent JVM termination.  A
405 +     * small but non-zero value (relative to a JVM's lifetime) seems
406 +     * best.
407 +     */
408 +    private static final long DEFAULT_KEEPALIVE_MILLIS = 10L;
409 +
410 +    /**
411       * Creates a new {@code ScheduledThreadPoolExecutor} with the
412       * given core pool size.
413       *
# Line 398 | Line 416 | public class ScheduledThreadPoolExecutor
416       * @throws IllegalArgumentException if {@code corePoolSize < 0}
417       */
418      public ScheduledThreadPoolExecutor(int corePoolSize) {
419 <        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
419 >        super(corePoolSize, Integer.MAX_VALUE,
420 >              DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
421                new DelayedWorkQueue());
422      }
423  
# Line 415 | Line 434 | public class ScheduledThreadPoolExecutor
434       */
435      public ScheduledThreadPoolExecutor(int corePoolSize,
436                                         ThreadFactory threadFactory) {
437 <        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
437 >        super(corePoolSize, Integer.MAX_VALUE,
438 >              DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
439                new DelayedWorkQueue(), threadFactory);
440      }
441  
442      /**
443 <     * Creates a new ScheduledThreadPoolExecutor with the given
444 <     * initial parameters.
443 >     * Creates a new {@code ScheduledThreadPoolExecutor} with the
444 >     * given initial parameters.
445       *
446       * @param corePoolSize the number of threads to keep in the pool, even
447       *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
# Line 432 | Line 452 | public class ScheduledThreadPoolExecutor
452       */
453      public ScheduledThreadPoolExecutor(int corePoolSize,
454                                         RejectedExecutionHandler handler) {
455 <        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
455 >        super(corePoolSize, Integer.MAX_VALUE,
456 >              DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
457                new DelayedWorkQueue(), handler);
458      }
459  
460      /**
461 <     * Creates a new ScheduledThreadPoolExecutor with the given
462 <     * initial parameters.
461 >     * Creates a new {@code ScheduledThreadPoolExecutor} with the
462 >     * given initial parameters.
463       *
464       * @param corePoolSize the number of threads to keep in the pool, even
465       *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
# Line 453 | Line 474 | public class ScheduledThreadPoolExecutor
474      public ScheduledThreadPoolExecutor(int corePoolSize,
475                                         ThreadFactory threadFactory,
476                                         RejectedExecutionHandler handler) {
477 <        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
477 >        super(corePoolSize, Integer.MAX_VALUE,
478 >              DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
479                new DelayedWorkQueue(), threadFactory, handler);
480      }
481  
482      /**
483 <     * Returns the trigger time of a delayed action.
483 >     * Returns the nanoTime-based trigger time of a delayed action.
484       */
485      private long triggerTime(long delay, TimeUnit unit) {
486          return triggerTime(unit.toNanos((delay < 0) ? 0 : delay));
487      }
488  
489      /**
490 <     * Returns the trigger time of a delayed action.
490 >     * Returns the nanoTime-based trigger time of a delayed action.
491       */
492      long triggerTime(long delay) {
493          return now() +
# Line 498 | Line 520 | public class ScheduledThreadPoolExecutor
520                                         TimeUnit unit) {
521          if (command == null || unit == null)
522              throw new NullPointerException();
523 <        RunnableScheduledFuture<?> t = decorateTask(command,
523 >        RunnableScheduledFuture<Void> t = decorateTask(command,
524              new ScheduledFutureTask<Void>(command, null,
525                                            triggerTime(delay, unit)));
526          delayedExecute(t);
# Line 747 | Line 769 | public class ScheduledThreadPoolExecutor
769       * fails to respond to interrupts may never terminate.
770       *
771       * @return list of tasks that never commenced execution.
772 <     *         Each element of this list is a {@link ScheduledFuture},
773 <     *         including those tasks submitted using {@code execute},
774 <     *         which are for scheduling purposes used as the basis of a
775 <     *         zero-delay {@code ScheduledFuture}.
772 >     *         Each element of this list is a {@link ScheduledFuture}.
773 >     *         For tasks submitted via one of the {@code schedule}
774 >     *         methods, the element will be identical to the returned
775 >     *         {@code ScheduledFuture}.  For tasks submitted using
776 >     *         {@link #execute}, the element will be a zero-delay {@code
777 >     *         ScheduledFuture}.
778       * @throws SecurityException {@inheritDoc}
779       */
780      public List<Runnable> shutdownNow() {
# Line 758 | Line 782 | public class ScheduledThreadPoolExecutor
782      }
783  
784      /**
785 <     * Returns the task queue used by this executor.  Each element of
786 <     * this queue is a {@link ScheduledFuture}, including those
787 <     * tasks submitted using {@code execute} which are for scheduling
788 <     * purposes used as the basis of a zero-delay
789 <     * {@code ScheduledFuture}.  Iteration over this queue is
790 <     * <em>not</em> guaranteed to traverse tasks in the order in
791 <     * which they will execute.
785 >     * Returns the task queue used by this executor.
786 >     * Each element of this list is a {@link ScheduledFuture}.
787 >     * For tasks submitted via one of the {@code schedule} methods, the
788 >     * element will be identical to the returned {@code ScheduledFuture}.
789 >     * For tasks submitted using {@link #execute}, the element will be a
790 >     * zero-delay {@code ScheduledFuture}.
791 >     *
792 >     * <p>Iteration over this queue is <em>not</em> guaranteed to traverse
793 >     * tasks in the order in which they will execute.
794       *
795       * @return the task queue
796       */
# Line 1224 | Line 1250 | public class ScheduledThreadPoolExecutor
1250           * Snapshot iterator that works off copy of underlying q array.
1251           */
1252          private class Itr implements Iterator<Runnable> {
1253 <            final RunnableScheduledFuture[] array;
1253 >            final RunnableScheduledFuture<?>[] array;
1254              int cursor = 0;     // index of next element to return
1255              int lastRet = -1;   // index of last element, or -1 if no such
1256  
1257 <            Itr(RunnableScheduledFuture[] array) {
1257 >            Itr(RunnableScheduledFuture<?>[] array) {
1258                  this.array = array;
1259              }
1260  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines