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