jdk/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java
author dl
Fri, 01 Aug 2008 00:42:43 -0700
changeset 1007 72a8a27e1d69
parent 61 5691b03db1ea
child 4110 ac033ba6ede4
permissions -rw-r--r--
6725789: ScheduledExecutorService does not work as expected in jdk7/6/5 Reviewed-by: martin, dholmes, chegar
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
     2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
 * This file is available under and governed by the GNU General Public
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
 * License version 2 only, as published by the Free Software Foundation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
 * However, the following notice accompanied the original version of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
 * file:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
 * Written by Doug Lea with assistance from members of JCP JSR-166
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
 * Expert Group and released to the public domain, as explained at
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
 * http://creativecommons.org/licenses/publicdomain
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
package java.util.concurrent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.util.concurrent.atomic.*;
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
    38
import java.util.concurrent.locks.*;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import java.util.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * A {@link ThreadPoolExecutor} that can additionally schedule
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * commands to run after a given delay, or to execute
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * periodically. This class is preferable to {@link java.util.Timer}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * when multiple worker threads are needed, or when the additional
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * flexibility or capabilities of {@link ThreadPoolExecutor} (which
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * this class extends) are required.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 *
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
    49
 * <p>Delayed tasks execute no sooner than they are enabled, but
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * without any real-time guarantees about when, after they are
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * enabled, they will commence. Tasks scheduled for exactly the same
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * execution time are enabled in first-in-first-out (FIFO) order of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * submission.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 *
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
    55
 * <p>When a submitted task is cancelled before it is run, execution
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
    56
 * is suppressed. By default, such a cancelled task is not
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
    57
 * automatically removed from the work queue until its delay
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
    58
 * elapses. While this enables further inspection and monitoring, it
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
    59
 * may also cause unbounded retention of cancelled tasks. To avoid
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
    60
 * this, set {@link #setRemoveOnCancelPolicy} to {@code true}, which
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
    61
 * causes tasks to be immediately removed from the work queue at
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
    62
 * time of cancellation.
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
    63
 *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 * <p>While this class inherits from {@link ThreadPoolExecutor}, a few
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 * of the inherited tuning methods are not useful for it. In
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 * particular, because it acts as a fixed-sized pool using
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 * {@code corePoolSize} threads and an unbounded queue, adjustments
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 * to {@code maximumPoolSize} have no useful effect. Additionally, it
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 * is almost never a good idea to set {@code corePoolSize} to zero or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 * use {@code allowCoreThreadTimeOut} because this may leave the pool
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 * without threads to handle tasks once they become eligible to run.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 * <p><b>Extension notes:</b> This class overrides the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 * {@link ThreadPoolExecutor#execute execute} and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
 * {@link AbstractExecutorService#submit(Runnable) submit}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
 * methods to generate internal {@link ScheduledFuture} objects to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
 * control per-task delays and scheduling.  To preserve
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
 * functionality, any further overrides of these methods in
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
 * subclasses must invoke superclass versions, which effectively
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
 * disables additional task customization.  However, this class
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
 * provides alternative protected extension method
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
 * {@code decorateTask} (one version each for {@code Runnable} and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
 * {@code Callable}) that can be used to customize the concrete task
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
 * types used to execute commands entered via {@code execute},
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
 * {@code submit}, {@code schedule}, {@code scheduleAtFixedRate},
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
 * and {@code scheduleWithFixedDelay}.  By default, a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
 * {@code ScheduledThreadPoolExecutor} uses a task type extending
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
 * {@link FutureTask}. However, this may be modified or replaced using
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
 * subclasses of the form:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
 *  <pre> {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
 * public class CustomScheduledExecutor extends ScheduledThreadPoolExecutor {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
 *   static class CustomTask<V> implements RunnableScheduledFuture<V> { ... }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
 *   protected <V> RunnableScheduledFuture<V> decorateTask(
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
 *                Runnable r, RunnableScheduledFuture<V> task) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
 *       return new CustomTask<V>(r, task);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
 *   }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
 *   protected <V> RunnableScheduledFuture<V> decorateTask(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
 *                Callable<V> c, RunnableScheduledFuture<V> task) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
 *       return new CustomTask<V>(c, task);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
 *   }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
 *   // ... add constructors, etc.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
 * }}</pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
 * @since 1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
 * @author Doug Lea
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
public class ScheduledThreadPoolExecutor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
        extends ThreadPoolExecutor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
        implements ScheduledExecutorService {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
     * This class specializes ThreadPoolExecutor implementation by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
     * 1. Using a custom task type, ScheduledFutureTask for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
     *    tasks, even those that don't require scheduling (i.e.,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
     *    those submitted using ExecutorService execute, not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
     *    ScheduledExecutorService methods) which are treated as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
     *    delayed tasks with a delay of zero.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
     *
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   124
     * 2. Using a custom queue (DelayedWorkQueue), a variant of
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
     *    unbounded DelayQueue. The lack of capacity constraint and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
     *    the fact that corePoolSize and maximumPoolSize are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
     *    effectively identical simplifies some execution mechanics
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   128
     *    (see delayedExecute) compared to ThreadPoolExecutor.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
     * 3. Supporting optional run-after-shutdown parameters, which
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
     *    leads to overrides of shutdown methods to remove and cancel
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
     *    tasks that should NOT be run after shutdown, as well as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
     *    different recheck logic when task (re)submission overlaps
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
     *    with a shutdown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
     * 4. Task decoration methods to allow interception and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
     *    instrumentation, which are needed because subclasses cannot
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
     *    otherwise override submit methods to get this effect. These
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
     *    don't have any impact on pool control logic though.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     * False if should cancel/suppress periodic tasks on shutdown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
    private volatile boolean continueExistingPeriodicTasksAfterShutdown;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
     * False if should cancel non-periodic tasks on shutdown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
    private volatile boolean executeExistingDelayedTasksAfterShutdown = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
    /**
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   153
     * True if ScheduledFutureTask.cancel should remove from queue
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   154
     */
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   155
    private volatile boolean removeOnCancel = false;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   156
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   157
    /**
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
     * Sequence number to break scheduling ties, and in turn to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
     * guarantee FIFO order among tied entries.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
    private static final AtomicLong sequencer = new AtomicLong(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
     * Returns current nanosecond time.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
    final long now() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        return System.nanoTime();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
    private class ScheduledFutureTask<V>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
            extends FutureTask<V> implements RunnableScheduledFuture<V> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
        /** Sequence number to break ties FIFO */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
        private final long sequenceNumber;
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   175
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        /** The time the task is enabled to execute in nanoTime units */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        private long time;
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   178
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
         * Period in nanoseconds for repeating tasks.  A positive
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
         * value indicates fixed-rate execution.  A negative value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
         * indicates fixed-delay execution.  A value of 0 indicates a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
         * non-repeating task.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
        private final long period;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
        /** The actual task to be re-enqueued by reExecutePeriodic */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
        RunnableScheduledFuture<V> outerTask = this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
        /**
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   191
         * Index into delay queue, to support faster cancellation.
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   192
         */
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   193
        int heapIndex;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   194
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   195
        /**
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
         * Creates a one-shot action with given nanoTime-based trigger time.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
        ScheduledFutureTask(Runnable r, V result, long ns) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
            super(r, result);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
            this.time = ns;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
            this.period = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
            this.sequenceNumber = sequencer.getAndIncrement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
         * Creates a periodic action with given nano time and period.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
        ScheduledFutureTask(Runnable r, V result, long ns, long period) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
            super(r, result);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
            this.time = ns;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
            this.period = period;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
            this.sequenceNumber = sequencer.getAndIncrement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
         * Creates a one-shot action with given nanoTime-based trigger.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
        ScheduledFutureTask(Callable<V> callable, long ns) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
            super(callable);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
            this.time = ns;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
            this.period = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
            this.sequenceNumber = sequencer.getAndIncrement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
        public long getDelay(TimeUnit unit) {
1007
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   226
            return unit.convert(time - now(), TimeUnit.NANOSECONDS);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
        public int compareTo(Delayed other) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
            if (other == this) // compare zero ONLY if same object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
                return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
            if (other instanceof ScheduledFutureTask) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
                ScheduledFutureTask<?> x = (ScheduledFutureTask<?>)other;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
                long diff = time - x.time;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
                if (diff < 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
                    return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
                else if (diff > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
                    return 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
                else if (sequenceNumber < x.sequenceNumber)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
                    return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
                else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
                    return 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
            long d = (getDelay(TimeUnit.NANOSECONDS) -
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
                      other.getDelay(TimeUnit.NANOSECONDS));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
            return (d == 0) ? 0 : ((d < 0) ? -1 : 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
         * Returns true if this is a periodic (not a one-shot) action.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
         * @return true if periodic
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
        public boolean isPeriodic() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
            return period != 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
         * Sets the next time to run for a periodic task.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
        private void setNextRunTime() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
            long p = period;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
            if (p > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
                time += p;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
            else
1007
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   266
                time = triggerTime(-p);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   269
        public boolean cancel(boolean mayInterruptIfRunning) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   270
            boolean cancelled = super.cancel(mayInterruptIfRunning);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   271
            if (cancelled && removeOnCancel && heapIndex >= 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   272
                remove(this);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   273
            return cancelled;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   274
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   275
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
         * Overrides FutureTask version so as to reset/requeue if periodic.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
        public void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
            boolean periodic = isPeriodic();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
            if (!canRunInCurrentRunState(periodic))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
                cancel(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
            else if (!periodic)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
                ScheduledFutureTask.super.run();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
            else if (ScheduledFutureTask.super.runAndReset()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
                setNextRunTime();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
                reExecutePeriodic(outerTask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
     * Returns true if can run a task given current run state
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
     * and run-after-shutdown parameters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
     * @param periodic true if this task periodic, false if delayed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
    boolean canRunInCurrentRunState(boolean periodic) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
        return isRunningOrShutdown(periodic ?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
                                   continueExistingPeriodicTasksAfterShutdown :
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
                                   executeExistingDelayedTasksAfterShutdown);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
     * Main execution method for delayed or periodic tasks.  If pool
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
     * is shut down, rejects the task. Otherwise adds task to queue
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
     * and starts a thread, if necessary, to run it.  (We cannot
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
     * prestart the thread to run the task because the task (probably)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
     * shouldn't be run yet,) If the pool is shut down while the task
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
     * is being added, cancel and remove it if required by state and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
     * run-after-shutdown parameters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
     * @param task the task
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
    private void delayedExecute(RunnableScheduledFuture<?> task) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
        if (isShutdown())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
            reject(task);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
            super.getQueue().add(task);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
            if (isShutdown() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
                !canRunInCurrentRunState(task.isPeriodic()) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
                remove(task))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
                task.cancel(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
            else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
                prestartCoreThread();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
     * Requeues a periodic task unless current run state precludes it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
     * Same idea as delayedExecute except drops task rather than rejecting.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
     * @param task the task
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
    void reExecutePeriodic(RunnableScheduledFuture<?> task) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
        if (canRunInCurrentRunState(true)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
            super.getQueue().add(task);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
            if (!canRunInCurrentRunState(true) && remove(task))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
                task.cancel(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
            else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
                prestartCoreThread();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
     * Cancels and clears the queue of all tasks that should not be run
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
     * due to shutdown policy.  Invoked within super.shutdown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
    @Override void onShutdown() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
        BlockingQueue<Runnable> q = super.getQueue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
        boolean keepDelayed =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
            getExecuteExistingDelayedTasksAfterShutdownPolicy();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
        boolean keepPeriodic =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
            getContinueExistingPeriodicTasksAfterShutdownPolicy();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
        if (!keepDelayed && !keepPeriodic)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
            q.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
            // Traverse snapshot to avoid iterator exceptions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
            for (Object e : q.toArray()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
                if (e instanceof RunnableScheduledFuture) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
                    RunnableScheduledFuture<?> t =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
                        (RunnableScheduledFuture<?>)e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
                    if ((t.isPeriodic() ? !keepPeriodic : !keepDelayed) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
                        t.isCancelled()) { // also remove if already cancelled
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
                        if (q.remove(t))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
                            t.cancel(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
        tryTerminate();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
     * Modifies or replaces the task used to execute a runnable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
     * This method can be used to override the concrete
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
     * class used for managing internal tasks.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
     * The default implementation simply returns the given task.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
     * @param runnable the submitted Runnable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
     * @param task the task created to execute the runnable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
     * @return a task that can execute the runnable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
     * @since 1.6
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
    protected <V> RunnableScheduledFuture<V> decorateTask(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
        Runnable runnable, RunnableScheduledFuture<V> task) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
        return task;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
     * Modifies or replaces the task used to execute a callable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
     * This method can be used to override the concrete
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
     * class used for managing internal tasks.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
     * The default implementation simply returns the given task.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
     * @param callable the submitted Callable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
     * @param task the task created to execute the callable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
     * @return a task that can execute the callable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
     * @since 1.6
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
    protected <V> RunnableScheduledFuture<V> decorateTask(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
        Callable<V> callable, RunnableScheduledFuture<V> task) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
        return task;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
     * Creates a new {@code ScheduledThreadPoolExecutor} with the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
     * given core pool size.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
     * @param corePoolSize the number of threads to keep in the pool, even
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
     * @throws IllegalArgumentException if {@code corePoolSize < 0}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
    public ScheduledThreadPoolExecutor(int corePoolSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
        super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
              new DelayedWorkQueue());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
     * Creates a new {@code ScheduledThreadPoolExecutor} with the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
     * given initial parameters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
     * @param corePoolSize the number of threads to keep in the pool, even
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
     * @param threadFactory the factory to use when the executor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
     *        creates a new thread
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
     * @throws IllegalArgumentException if {@code corePoolSize < 0}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
     * @throws NullPointerException if {@code threadFactory} is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
    public ScheduledThreadPoolExecutor(int corePoolSize,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
                             ThreadFactory threadFactory) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
        super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
              new DelayedWorkQueue(), threadFactory);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
     * Creates a new ScheduledThreadPoolExecutor with the given
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
     * initial parameters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
     * @param corePoolSize the number of threads to keep in the pool, even
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
     * @param handler the handler to use when execution is blocked
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
     *        because the thread bounds and queue capacities are reached
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
     * @throws IllegalArgumentException if {@code corePoolSize < 0}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
     * @throws NullPointerException if {@code handler} is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
    public ScheduledThreadPoolExecutor(int corePoolSize,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
                              RejectedExecutionHandler handler) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
        super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
              new DelayedWorkQueue(), handler);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
     * Creates a new ScheduledThreadPoolExecutor with the given
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
     * initial parameters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
     * @param corePoolSize the number of threads to keep in the pool, even
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
     * @param threadFactory the factory to use when the executor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
     *        creates a new thread
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
     * @param handler the handler to use when execution is blocked
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
     *        because the thread bounds and queue capacities are reached
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
     * @throws IllegalArgumentException if {@code corePoolSize < 0}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
     * @throws NullPointerException if {@code threadFactory} or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
     *         {@code handler} is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
    public ScheduledThreadPoolExecutor(int corePoolSize,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
                              ThreadFactory threadFactory,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
                              RejectedExecutionHandler handler) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
        super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
              new DelayedWorkQueue(), threadFactory, handler);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
    /**
1007
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   475
     * Returns the trigger time of a delayed action.
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   476
     */
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   477
    private long triggerTime(long delay, TimeUnit unit) {
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   478
        return triggerTime(unit.toNanos((delay < 0) ? 0 : delay));
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   479
    }
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   480
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   481
    /**
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   482
     * Returns the trigger time of a delayed action.
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   483
     */
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   484
    long triggerTime(long delay) {
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   485
        return now() +
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   486
            ((delay < (Long.MAX_VALUE >> 1)) ? delay : overflowFree(delay));
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   487
    }
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   488
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   489
    /**
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   490
     * Constrains the values of all delays in the queue to be within
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   491
     * Long.MAX_VALUE of each other, to avoid overflow in compareTo.
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   492
     * This may occur if a task is eligible to be dequeued, but has
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   493
     * not yet been, while some other task is added with a delay of
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   494
     * Long.MAX_VALUE.
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   495
     */
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   496
    private long overflowFree(long delay) {
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   497
        Delayed head = (Delayed) super.getQueue().peek();
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   498
        if (head != null) {
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   499
            long headDelay = head.getDelay(TimeUnit.NANOSECONDS);
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   500
            if (headDelay < 0 && (delay - headDelay < 0))
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   501
                delay = Long.MAX_VALUE + headDelay;
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   502
        }
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   503
        return delay;
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   504
    }
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   505
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   506
    /**
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
     * @throws RejectedExecutionException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
     * @throws NullPointerException       {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
    public ScheduledFuture<?> schedule(Runnable command,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
                                       long delay,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
                                       TimeUnit unit) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
        if (command == null || unit == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
            throw new NullPointerException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
        RunnableScheduledFuture<?> t = decorateTask(command,
1007
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   516
            new ScheduledFutureTask<Void>(command, null,
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   517
                                          triggerTime(delay, unit)));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
        delayedExecute(t);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
        return t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
     * @throws RejectedExecutionException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
     * @throws NullPointerException       {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
    public <V> ScheduledFuture<V> schedule(Callable<V> callable,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
                                           long delay,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
                                           TimeUnit unit) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
        if (callable == null || unit == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
            throw new NullPointerException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
        RunnableScheduledFuture<V> t = decorateTask(callable,
1007
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   532
            new ScheduledFutureTask<V>(callable,
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   533
                                       triggerTime(delay, unit)));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
        delayedExecute(t);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
        return t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
     * @throws RejectedExecutionException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
     * @throws NullPointerException       {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
     * @throws IllegalArgumentException   {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
                                                  long initialDelay,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
                                                  long period,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
                                                  TimeUnit unit) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
        if (command == null || unit == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
            throw new NullPointerException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
        if (period <= 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
            throw new IllegalArgumentException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
        ScheduledFutureTask<Void> sft =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
            new ScheduledFutureTask<Void>(command,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
                                          null,
1007
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   554
                                          triggerTime(initialDelay, unit),
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
                                          unit.toNanos(period));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
        RunnableScheduledFuture<Void> t = decorateTask(command, sft);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
        sft.outerTask = t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
        delayedExecute(t);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
        return t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
     * @throws RejectedExecutionException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
     * @throws NullPointerException       {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
     * @throws IllegalArgumentException   {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
    public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
                                                     long initialDelay,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
                                                     long delay,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
                                                     TimeUnit unit) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
        if (command == null || unit == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
            throw new NullPointerException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
        if (delay <= 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
            throw new IllegalArgumentException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
        ScheduledFutureTask<Void> sft =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
            new ScheduledFutureTask<Void>(command,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
                                          null,
1007
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   578
                                          triggerTime(initialDelay, unit),
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
                                          unit.toNanos(-delay));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
        RunnableScheduledFuture<Void> t = decorateTask(command, sft);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
        sft.outerTask = t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
        delayedExecute(t);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
        return t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
     * Executes {@code command} with zero required delay.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
     * This has effect equivalent to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
     * {@link #schedule(Runnable,long,TimeUnit) schedule(command, 0, anyUnit)}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
     * Note that inspections of the queue and of the list returned by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
     * {@code shutdownNow} will access the zero-delayed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
     * {@link ScheduledFuture}, not the {@code command} itself.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
     * <p>A consequence of the use of {@code ScheduledFuture} objects is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
     * that {@link ThreadPoolExecutor#afterExecute afterExecute} is always
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
     * called with a null second {@code Throwable} argument, even if the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
     * {@code command} terminated abruptly.  Instead, the {@code Throwable}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
     * thrown by such a task can be obtained via {@link Future#get}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
     * @throws RejectedExecutionException at discretion of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
     *         {@code RejectedExecutionHandler}, if the task
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
     *         cannot be accepted for execution because the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
     *         executor has been shut down
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
     * @throws NullPointerException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
    public void execute(Runnable command) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
        schedule(command, 0, TimeUnit.NANOSECONDS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
    // Override AbstractExecutorService methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
     * @throws RejectedExecutionException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
     * @throws NullPointerException       {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
    public Future<?> submit(Runnable task) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
        return schedule(task, 0, TimeUnit.NANOSECONDS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
     * @throws RejectedExecutionException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
     * @throws NullPointerException       {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
    public <T> Future<T> submit(Runnable task, T result) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
        return schedule(Executors.callable(task, result),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
                        0, TimeUnit.NANOSECONDS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
     * @throws RejectedExecutionException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
     * @throws NullPointerException       {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
    public <T> Future<T> submit(Callable<T> task) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
        return schedule(task, 0, TimeUnit.NANOSECONDS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
     * Sets the policy on whether to continue executing existing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
     * periodic tasks even when this executor has been {@code shutdown}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
     * In this case, these tasks will only terminate upon
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
     * {@code shutdownNow} or after setting the policy to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
     * {@code false} when already shutdown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
     * This value is by default {@code false}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
     * @param value if {@code true}, continue after shutdown, else don't.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
     * @see #getContinueExistingPeriodicTasksAfterShutdownPolicy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
    public void setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
        continueExistingPeriodicTasksAfterShutdown = value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
        if (!value && isShutdown())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
            onShutdown();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
     * Gets the policy on whether to continue executing existing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
     * periodic tasks even when this executor has been {@code shutdown}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
     * In this case, these tasks will only terminate upon
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
     * {@code shutdownNow} or after setting the policy to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
     * {@code false} when already shutdown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
     * This value is by default {@code false}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
     * @return {@code true} if will continue after shutdown
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
     * @see #setContinueExistingPeriodicTasksAfterShutdownPolicy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
    public boolean getContinueExistingPeriodicTasksAfterShutdownPolicy() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
        return continueExistingPeriodicTasksAfterShutdown;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
     * Sets the policy on whether to execute existing delayed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
     * tasks even when this executor has been {@code shutdown}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
     * In this case, these tasks will only terminate upon
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
     * {@code shutdownNow}, or after setting the policy to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
     * {@code false} when already shutdown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
     * This value is by default {@code true}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
     * @param value if {@code true}, execute after shutdown, else don't.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
     * @see #getExecuteExistingDelayedTasksAfterShutdownPolicy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
    public void setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
        executeExistingDelayedTasksAfterShutdown = value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
        if (!value && isShutdown())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
            onShutdown();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
     * Gets the policy on whether to execute existing delayed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
     * tasks even when this executor has been {@code shutdown}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
     * In this case, these tasks will only terminate upon
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
     * {@code shutdownNow}, or after setting the policy to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
     * {@code false} when already shutdown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
     * This value is by default {@code true}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
     * @return {@code true} if will execute after shutdown
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
     * @see #setExecuteExistingDelayedTasksAfterShutdownPolicy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
    public boolean getExecuteExistingDelayedTasksAfterShutdownPolicy() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
        return executeExistingDelayedTasksAfterShutdown;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
    /**
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   702
     * Sets the policy on whether cancelled tasks should be immediately
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   703
     * removed from the work queue at time of cancellation.  This value is
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   704
     * by default {@code false}.
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   705
     *
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   706
     * @param value if {@code true}, remove on cancellation, else don't
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   707
     * @see #getRemoveOnCancelPolicy
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   708
     * @since 1.7
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   709
     */
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   710
    public void setRemoveOnCancelPolicy(boolean value) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   711
        removeOnCancel = value;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   712
    }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   713
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   714
    /**
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   715
     * Gets the policy on whether cancelled tasks should be immediately
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   716
     * removed from the work queue at time of cancellation.  This value is
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   717
     * by default {@code false}.
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   718
     *
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   719
     * @return {@code true} if cancelled tasks are immediately removed
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   720
     *         from the queue
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   721
     * @see #setRemoveOnCancelPolicy
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   722
     * @since 1.7
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   723
     */
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   724
    public boolean getRemoveOnCancelPolicy() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   725
        return removeOnCancel;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   726
    }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   727
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   728
    /**
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
     * Initiates an orderly shutdown in which previously submitted
61
5691b03db1ea 6620549: ExecutorService#shutdown should clearly state that it does not block
martin
parents: 59
diff changeset
   730
     * tasks are executed, but no new tasks will be accepted.
5691b03db1ea 6620549: ExecutorService#shutdown should clearly state that it does not block
martin
parents: 59
diff changeset
   731
     * Invocation has no additional effect if already shut down.
5691b03db1ea 6620549: ExecutorService#shutdown should clearly state that it does not block
martin
parents: 59
diff changeset
   732
     *
5691b03db1ea 6620549: ExecutorService#shutdown should clearly state that it does not block
martin
parents: 59
diff changeset
   733
     * <p>This method does not wait for previously submitted tasks to
5691b03db1ea 6620549: ExecutorService#shutdown should clearly state that it does not block
martin
parents: 59
diff changeset
   734
     * complete execution.  Use {@link #awaitTermination awaitTermination}
5691b03db1ea 6620549: ExecutorService#shutdown should clearly state that it does not block
martin
parents: 59
diff changeset
   735
     * to do that.
5691b03db1ea 6620549: ExecutorService#shutdown should clearly state that it does not block
martin
parents: 59
diff changeset
   736
     *
5691b03db1ea 6620549: ExecutorService#shutdown should clearly state that it does not block
martin
parents: 59
diff changeset
   737
     * <p>If the {@code ExecuteExistingDelayedTasksAfterShutdownPolicy}
5691b03db1ea 6620549: ExecutorService#shutdown should clearly state that it does not block
martin
parents: 59
diff changeset
   738
     * has been set {@code false}, existing delayed tasks whose delays
5691b03db1ea 6620549: ExecutorService#shutdown should clearly state that it does not block
martin
parents: 59
diff changeset
   739
     * have not yet elapsed are cancelled.  And unless the {@code
5691b03db1ea 6620549: ExecutorService#shutdown should clearly state that it does not block
martin
parents: 59
diff changeset
   740
     * ContinueExistingPeriodicTasksAfterShutdownPolicy} has been set
5691b03db1ea 6620549: ExecutorService#shutdown should clearly state that it does not block
martin
parents: 59
diff changeset
   741
     * {@code true}, future executions of existing periodic tasks will
5691b03db1ea 6620549: ExecutorService#shutdown should clearly state that it does not block
martin
parents: 59
diff changeset
   742
     * be cancelled.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
     * @throws SecurityException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
    public void shutdown() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
        super.shutdown();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
     * Attempts to stop all actively executing tasks, halts the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
     * processing of waiting tasks, and returns a list of the tasks
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
     * that were awaiting execution.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
     *
61
5691b03db1ea 6620549: ExecutorService#shutdown should clearly state that it does not block
martin
parents: 59
diff changeset
   755
     * <p>This method does not wait for actively executing tasks to
5691b03db1ea 6620549: ExecutorService#shutdown should clearly state that it does not block
martin
parents: 59
diff changeset
   756
     * terminate.  Use {@link #awaitTermination awaitTermination} to
5691b03db1ea 6620549: ExecutorService#shutdown should clearly state that it does not block
martin
parents: 59
diff changeset
   757
     * do that.
5691b03db1ea 6620549: ExecutorService#shutdown should clearly state that it does not block
martin
parents: 59
diff changeset
   758
     *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
     * <p>There are no guarantees beyond best-effort attempts to stop
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
     * processing actively executing tasks.  This implementation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
     * cancels tasks via {@link Thread#interrupt}, so any task that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
     * fails to respond to interrupts may never terminate.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
     * @return list of tasks that never commenced execution.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
     *         Each element of this list is a {@link ScheduledFuture},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
     *         including those tasks submitted using {@code execute},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
     *         which are for scheduling purposes used as the basis of a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
     *         zero-delay {@code ScheduledFuture}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
     * @throws SecurityException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
    public List<Runnable> shutdownNow() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
        return super.shutdownNow();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
     * Returns the task queue used by this executor.  Each element of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
     * this queue is a {@link ScheduledFuture}, including those
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
     * tasks submitted using {@code execute} which are for scheduling
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
     * purposes used as the basis of a zero-delay
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
     * {@code ScheduledFuture}.  Iteration over this queue is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
     * <em>not</em> guaranteed to traverse tasks in the order in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
     * which they will execute.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
     * @return the task queue
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
    public BlockingQueue<Runnable> getQueue() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
        return super.getQueue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
    /**
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   791
     * Specialized delay queue. To mesh with TPE declarations, this
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   792
     * class must be declared as a BlockingQueue<Runnable> even though
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   793
     * it can only hold RunnableScheduledFutures.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
     */
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   795
    static class DelayedWorkQueue extends AbstractQueue<Runnable>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
        implements BlockingQueue<Runnable> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   798
        /*
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   799
         * A DelayedWorkQueue is based on a heap-based data structure
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   800
         * like those in DelayQueue and PriorityQueue, except that
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   801
         * every ScheduledFutureTask also records its index into the
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   802
         * heap array. This eliminates the need to find a task upon
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   803
         * cancellation, greatly speeding up removal (down from O(n)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   804
         * to O(log n)), and reducing garbage retention that would
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   805
         * otherwise occur by waiting for the element to rise to top
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   806
         * before clearing. But because the queue may also hold
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   807
         * RunnableScheduledFutures that are not ScheduledFutureTasks,
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   808
         * we are not guaranteed to have such indices available, in
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   809
         * which case we fall back to linear search. (We expect that
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   810
         * most tasks will not be decorated, and that the faster cases
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   811
         * will be much more common.)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   812
         *
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   813
         * All heap operations must record index changes -- mainly
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   814
         * within siftUp and siftDown. Upon removal, a task's
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   815
         * heapIndex is set to -1. Note that ScheduledFutureTasks can
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   816
         * appear at most once in the queue (this need not be true for
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   817
         * other kinds of tasks or work queues), so are uniquely
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   818
         * identified by heapIndex.
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   819
         */
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   820
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   821
        private static final int INITIAL_CAPACITY = 16;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   822
        private RunnableScheduledFuture[] queue =
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   823
            new RunnableScheduledFuture[INITIAL_CAPACITY];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   824
        private final ReentrantLock lock = new ReentrantLock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   825
        private int size = 0;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   826
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   827
        /**
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   828
         * Thread designated to wait for the task at the head of the
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   829
         * queue.  This variant of the Leader-Follower pattern
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   830
         * (http://www.cs.wustl.edu/~schmidt/POSA/POSA2/) serves to
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   831
         * minimize unnecessary timed waiting.  When a thread becomes
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   832
         * the leader, it waits only for the next delay to elapse, but
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   833
         * other threads await indefinitely.  The leader thread must
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   834
         * signal some other thread before returning from take() or
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   835
         * poll(...), unless some other thread becomes leader in the
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   836
         * interim.  Whenever the head of the queue is replaced with a
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   837
         * task with an earlier expiration time, the leader field is
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   838
         * invalidated by being reset to null, and some waiting
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   839
         * thread, but not necessarily the current leader, is
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   840
         * signalled.  So waiting threads must be prepared to acquire
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   841
         * and lose leadership while waiting.
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   842
         */
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   843
        private Thread leader = null;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   844
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   845
        /**
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   846
         * Condition signalled when a newer task becomes available at the
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   847
         * head of the queue or a new thread may need to become leader.
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   848
         */
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   849
        private final Condition available = lock.newCondition();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   850
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   851
        /**
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   852
         * Set f's heapIndex if it is a ScheduledFutureTask.
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   853
         */
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   854
        private void setIndex(RunnableScheduledFuture f, int idx) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   855
            if (f instanceof ScheduledFutureTask)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   856
                ((ScheduledFutureTask)f).heapIndex = idx;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   857
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   858
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   859
        /**
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   860
         * Sift element added at bottom up to its heap-ordered spot.
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   861
         * Call only when holding lock.
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   862
         */
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   863
        private void siftUp(int k, RunnableScheduledFuture key) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   864
            while (k > 0) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   865
                int parent = (k - 1) >>> 1;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   866
                RunnableScheduledFuture e = queue[parent];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   867
                if (key.compareTo(e) >= 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   868
                    break;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   869
                queue[k] = e;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   870
                setIndex(e, k);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   871
                k = parent;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   872
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   873
            queue[k] = key;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   874
            setIndex(key, k);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   875
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   876
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   877
        /**
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   878
         * Sift element added at top down to its heap-ordered spot.
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   879
         * Call only when holding lock.
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   880
         */
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   881
        private void siftDown(int k, RunnableScheduledFuture key) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   882
            int half = size >>> 1;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   883
            while (k < half) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   884
                int child = (k << 1) + 1;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   885
                RunnableScheduledFuture c = queue[child];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   886
                int right = child + 1;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   887
                if (right < size && c.compareTo(queue[right]) > 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   888
                    c = queue[child = right];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   889
                if (key.compareTo(c) <= 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   890
                    break;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   891
                queue[k] = c;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   892
                setIndex(c, k);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   893
                k = child;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   894
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   895
            queue[k] = key;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   896
            setIndex(key, k);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   897
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   898
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   899
        /**
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   900
         * Resize the heap array.  Call only when holding lock.
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   901
         */
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   902
        private void grow() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   903
            int oldCapacity = queue.length;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   904
            int newCapacity = oldCapacity + (oldCapacity >> 1); // grow 50%
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   905
            if (newCapacity < 0) // overflow
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   906
                newCapacity = Integer.MAX_VALUE;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   907
            queue = Arrays.copyOf(queue, newCapacity);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   908
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   909
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   910
        /**
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   911
         * Find index of given object, or -1 if absent
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   912
         */
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   913
        private int indexOf(Object x) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   914
            if (x != null) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   915
                if (x instanceof ScheduledFutureTask) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   916
                    int i = ((ScheduledFutureTask) x).heapIndex;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   917
                    // Sanity check; x could conceivably be a
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   918
                    // ScheduledFutureTask from some other pool.
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   919
                    if (i >= 0 && i < size && queue[i] == x)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   920
                        return i;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   921
                } else {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   922
                    for (int i = 0; i < size; i++)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   923
                        if (x.equals(queue[i]))
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   924
                            return i;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   925
                }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   926
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   927
            return -1;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   928
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   929
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   930
        public boolean contains(Object x) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   931
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   932
            lock.lock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   933
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   934
                return indexOf(x) != -1;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   935
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   936
                lock.unlock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   937
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   938
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   939
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   940
        public boolean remove(Object x) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   941
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   942
            lock.lock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   943
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   944
                int i = indexOf(x);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   945
                if (i < 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   946
                    return false;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   947
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   948
                setIndex(queue[i], -1);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   949
                int s = --size;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   950
                RunnableScheduledFuture replacement = queue[s];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   951
                queue[s] = null;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   952
                if (s != i) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   953
                    siftDown(i, replacement);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   954
                    if (queue[i] == replacement)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   955
                        siftUp(i, replacement);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   956
                }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   957
                return true;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   958
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   959
                lock.unlock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   960
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   961
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   962
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   963
        public int size() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   964
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   965
            lock.lock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   966
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   967
                return size;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   968
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   969
                lock.unlock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   970
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   971
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   972
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   973
        public boolean isEmpty() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   974
            return size() == 0;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   975
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   976
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   977
        public int remainingCapacity() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   978
            return Integer.MAX_VALUE;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   979
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   980
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   981
        public RunnableScheduledFuture peek() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   982
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   983
            lock.lock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   984
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   985
                return queue[0];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   986
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   987
                lock.unlock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   988
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   989
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   990
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   991
        public boolean offer(Runnable x) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   992
            if (x == null)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   993
                throw new NullPointerException();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   994
            RunnableScheduledFuture e = (RunnableScheduledFuture)x;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   995
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   996
            lock.lock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   997
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   998
                int i = size;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   999
                if (i >= queue.length)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1000
                    grow();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1001
                size = i + 1;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1002
                if (i == 0) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1003
                    queue[0] = e;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1004
                    setIndex(e, 0);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1005
                } else {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1006
                    siftUp(i, e);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1007
                }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1008
                if (queue[0] == e) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1009
                    leader = null;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1010
                    available.signal();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1011
                }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1012
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1013
                lock.unlock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1014
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1015
            return true;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1016
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1017
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1018
        public void put(Runnable e) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1019
            offer(e);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1020
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1021
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1022
        public boolean add(Runnable e) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1023
            return offer(e);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1026
        public boolean offer(Runnable e, long timeout, TimeUnit unit) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1027
            return offer(e);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
        }
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1029
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1030
        /**
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1031
         * Performs common bookkeeping for poll and take: Replaces
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1032
         * first element with last and sifts it down.  Call only when
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1033
         * holding lock.
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1034
         * @param f the task to remove and return
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1035
         */
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1036
        private RunnableScheduledFuture finishPoll(RunnableScheduledFuture f) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1037
            int s = --size;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1038
            RunnableScheduledFuture x = queue[s];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1039
            queue[s] = null;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1040
            if (s != 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1041
                siftDown(0, x);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1042
            setIndex(f, -1);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1043
            return f;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1044
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1045
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1046
        public RunnableScheduledFuture poll() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1047
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1048
            lock.lock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1049
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1050
                RunnableScheduledFuture first = queue[0];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1051
                if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1052
                    return null;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1053
                else
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1054
                    return finishPoll(first);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1055
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1056
                lock.unlock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1057
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
        }
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1059
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1060
        public RunnableScheduledFuture take() throws InterruptedException {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1061
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1062
            lock.lockInterruptibly();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1063
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1064
                for (;;) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1065
                    RunnableScheduledFuture first = queue[0];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1066
                    if (first == null)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1067
                        available.await();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1068
                    else {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1069
                        long delay = first.getDelay(TimeUnit.NANOSECONDS);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1070
                        if (delay <= 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1071
                            return finishPoll(first);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1072
                        else if (leader != null)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1073
                            available.await();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1074
                        else {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1075
                            Thread thisThread = Thread.currentThread();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1076
                            leader = thisThread;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1077
                            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1078
                                available.awaitNanos(delay);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1079
                            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1080
                                if (leader == thisThread)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1081
                                    leader = null;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1082
                            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1083
                        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1084
                    }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1085
                }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1086
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1087
                if (leader == null && queue[0] != null)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1088
                    available.signal();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1089
                lock.unlock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1090
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
        }
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1092
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1093
        public RunnableScheduledFuture poll(long timeout, TimeUnit unit)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1094
            throws InterruptedException {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1095
            long nanos = unit.toNanos(timeout);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1096
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1097
            lock.lockInterruptibly();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1098
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1099
                for (;;) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1100
                    RunnableScheduledFuture first = queue[0];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1101
                    if (first == null) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1102
                        if (nanos <= 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1103
                            return null;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1104
                        else
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1105
                            nanos = available.awaitNanos(nanos);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1106
                    } else {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1107
                        long delay = first.getDelay(TimeUnit.NANOSECONDS);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1108
                        if (delay <= 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1109
                            return finishPoll(first);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1110
                        if (nanos <= 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1111
                            return null;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1112
                        if (nanos < delay || leader != null)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1113
                            nanos = available.awaitNanos(nanos);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1114
                        else {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1115
                            Thread thisThread = Thread.currentThread();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1116
                            leader = thisThread;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1117
                            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1118
                                long timeLeft = available.awaitNanos(delay);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1119
                                nanos -= delay - timeLeft;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1120
                            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1121
                                if (leader == thisThread)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1122
                                    leader = null;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1123
                            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1124
                        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1125
                    }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1126
                }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1127
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1128
                if (leader == null && queue[0] != null)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1129
                    available.signal();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1130
                lock.unlock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1131
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1134
        public void clear() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1135
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1136
            lock.lock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1137
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1138
                for (int i = 0; i < size; i++) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1139
                    RunnableScheduledFuture t = queue[i];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1140
                    if (t != null) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1141
                        queue[i] = null;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1142
                        setIndex(t, -1);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1143
                    }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1144
                }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1145
                size = 0;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1146
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1147
                lock.unlock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1148
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1149
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1150
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1151
        /**
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1152
         * Return and remove first element only if it is expired.
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1153
         * Used only by drainTo.  Call only when holding lock.
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1154
         */
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1155
        private RunnableScheduledFuture pollExpired() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1156
            RunnableScheduledFuture first = queue[0];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1157
            if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1158
                return null;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1159
            return finishPoll(first);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1160
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1161
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1162
        public int drainTo(Collection<? super Runnable> c) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1163
            if (c == null)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1164
                throw new NullPointerException();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1165
            if (c == this)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1166
                throw new IllegalArgumentException();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1167
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1168
            lock.lock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1169
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1170
                RunnableScheduledFuture first;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1171
                int n = 0;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1172
                while ((first = pollExpired()) != null) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1173
                    c.add(first);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1174
                    ++n;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1175
                }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1176
                return n;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1177
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1178
                lock.unlock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1179
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1182
        public int drainTo(Collection<? super Runnable> c, int maxElements) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1183
            if (c == null)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1184
                throw new NullPointerException();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1185
            if (c == this)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1186
                throw new IllegalArgumentException();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1187
            if (maxElements <= 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1188
                return 0;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1189
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1190
            lock.lock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1191
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1192
                RunnableScheduledFuture first;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1193
                int n = 0;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1194
                while (n < maxElements && (first = pollExpired()) != null) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1195
                    c.add(first);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1196
                    ++n;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1197
                }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1198
                return n;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1199
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1200
                lock.unlock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1201
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1202
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1203
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1204
        public Object[] toArray() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1205
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1206
            lock.lock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1207
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1208
                return Arrays.copyOf(queue, size, Object[].class);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1209
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1210
                lock.unlock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1211
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1212
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1213
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1214
        @SuppressWarnings("unchecked")
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1215
        public <T> T[] toArray(T[] a) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1216
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1217
            lock.lock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1218
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1219
                if (a.length < size)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1220
                    return (T[]) Arrays.copyOf(queue, size, a.getClass());
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1221
                System.arraycopy(queue, 0, a, 0, size);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1222
                if (a.length > size)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1223
                    a[size] = null;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1224
                return a;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1225
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1226
                lock.unlock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1227
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1228
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1229
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1230
        public Iterator<Runnable> iterator() {
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1231
            return new Itr(Arrays.copyOf(queue, size));
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1232
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1233
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1234
        /**
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1235
         * Snapshot iterator that works off copy of underlying q array.
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1236
         */
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1237
        private class Itr implements Iterator<Runnable> {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1238
            final RunnableScheduledFuture[] array;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1239
            int cursor = 0;     // index of next element to return
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1240
            int lastRet = -1;   // index of last element, or -1 if no such
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1241
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1242
            Itr(RunnableScheduledFuture[] array) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1243
                this.array = array;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1244
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1245
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1246
            public boolean hasNext() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1247
                return cursor < array.length;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1248
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1249
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1250
            public Runnable next() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1251
                if (cursor >= array.length)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1252
                    throw new NoSuchElementException();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1253
                lastRet = cursor;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1254
                return array[cursor++];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1255
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1256
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1257
            public void remove() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1258
                if (lastRet < 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1259
                    throw new IllegalStateException();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1260
                DelayedWorkQueue.this.remove(array[lastRet]);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1261
                lastRet = -1;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1262
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1263
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1264
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1265
}