jdk/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java
author dl
Wed, 01 Dec 2010 21:46:52 +0000
changeset 7518 0282db800fe1
parent 5506 202f599c92aa
child 7976 f273c0d04215
permissions -rw-r--r--
7003745: Code style cleanups (sync from Dougs CVS) Reviewed-by: chegar, dholmes
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();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
        if (!keepDelayed && !keepPeriodic)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
            q.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
            // Traverse snapshot to avoid iterator exceptions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
            for (Object e : q.toArray()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
                if (e instanceof RunnableScheduledFuture) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
                    RunnableScheduledFuture<?> t =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
                        (RunnableScheduledFuture<?>)e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
                    if ((t.isPeriodic() ? !keepPeriodic : !keepDelayed) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
                        t.isCancelled()) { // also remove if already cancelled
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
                        if (q.remove(t))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
                            t.cancel(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
        tryTerminate();
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
     * Modifies or replaces the task used to execute a runnable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
     * This method can be used to override the concrete
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
     * class used for managing internal tasks.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
     * The default implementation simply returns the given task.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
     * @param runnable the submitted Runnable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
     * @param task the task created to execute the runnable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
     * @return a task that can execute the runnable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
     * @since 1.6
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
    protected <V> RunnableScheduledFuture<V> decorateTask(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        Runnable runnable, RunnableScheduledFuture<V> task) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
        return task;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
     * Modifies or replaces the task used to execute a callable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
     * This method can be used to override the concrete
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
     * class used for managing internal tasks.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
     * The default implementation simply returns the given task.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
     * @param callable the submitted Callable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
     * @param task the task created to execute the callable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
     * @return a task that can execute the callable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
     * @since 1.6
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
    protected <V> RunnableScheduledFuture<V> decorateTask(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
        Callable<V> callable, RunnableScheduledFuture<V> task) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
        return task;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
     * Creates a new {@code ScheduledThreadPoolExecutor} with the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
     * given core pool size.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
     * @param corePoolSize the number of threads to keep in the pool, even
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
     * @throws IllegalArgumentException if {@code corePoolSize < 0}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
    public ScheduledThreadPoolExecutor(int corePoolSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
        super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
              new DelayedWorkQueue());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
     * Creates a new {@code ScheduledThreadPoolExecutor} with the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
     * given initial parameters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
     * @param corePoolSize the number of threads to keep in the pool, even
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
     * @param threadFactory the factory to use when the executor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
     *        creates a new thread
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
     * @throws IllegalArgumentException if {@code corePoolSize < 0}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
     * @throws NullPointerException if {@code threadFactory} is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
    public ScheduledThreadPoolExecutor(int corePoolSize,
7518
0282db800fe1 7003745: Code style cleanups (sync from Dougs CVS)
dl
parents: 5506
diff changeset
   439
                                       ThreadFactory threadFactory) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
        super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
              new DelayedWorkQueue(), threadFactory);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
     * Creates a new ScheduledThreadPoolExecutor with the given
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
     * initial parameters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
     * @param corePoolSize the number of threads to keep in the pool, even
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
     * @param handler the handler to use when execution is blocked
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
     *        because the thread bounds and queue capacities are reached
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
     * @throws IllegalArgumentException if {@code corePoolSize < 0}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
     * @throws NullPointerException if {@code handler} is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
    public ScheduledThreadPoolExecutor(int corePoolSize,
7518
0282db800fe1 7003745: Code style cleanups (sync from Dougs CVS)
dl
parents: 5506
diff changeset
   456
                                       RejectedExecutionHandler handler) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
        super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
              new DelayedWorkQueue(), handler);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
     * Creates a new ScheduledThreadPoolExecutor with the given
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
     * initial parameters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
     * @param corePoolSize the number of threads to keep in the pool, even
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
     * @param threadFactory the factory to use when the executor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
     *        creates a new thread
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
     * @param handler the handler to use when execution is blocked
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
     *        because the thread bounds and queue capacities are reached
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
     * @throws IllegalArgumentException if {@code corePoolSize < 0}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
     * @throws NullPointerException if {@code threadFactory} or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
     *         {@code handler} is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
    public ScheduledThreadPoolExecutor(int corePoolSize,
7518
0282db800fe1 7003745: Code style cleanups (sync from Dougs CVS)
dl
parents: 5506
diff changeset
   476
                                       ThreadFactory threadFactory,
0282db800fe1 7003745: Code style cleanups (sync from Dougs CVS)
dl
parents: 5506
diff changeset
   477
                                       RejectedExecutionHandler handler) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
        super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
              new DelayedWorkQueue(), threadFactory, handler);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
    /**
1007
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   483
     * 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
   484
     */
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   485
    private long triggerTime(long delay, TimeUnit unit) {
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   486
        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
   487
    }
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   488
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   489
    /**
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   490
     * 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
   491
     */
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   492
    long triggerTime(long delay) {
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   493
        return now() +
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   494
            ((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
   495
    }
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   496
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   497
    /**
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   498
     * 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
   499
     * 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
   500
     * 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
   501
     * 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
   502
     * Long.MAX_VALUE.
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   503
     */
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   504
    private long overflowFree(long delay) {
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   505
        Delayed head = (Delayed) super.getQueue().peek();
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   506
        if (head != null) {
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   507
            long headDelay = head.getDelay(TimeUnit.NANOSECONDS);
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   508
            if (headDelay < 0 && (delay - headDelay < 0))
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   509
                delay = Long.MAX_VALUE + headDelay;
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   510
        }
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   511
        return delay;
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   512
    }
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   513
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   514
    /**
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
     * @throws RejectedExecutionException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
     * @throws NullPointerException       {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
    public ScheduledFuture<?> schedule(Runnable command,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
                                       long delay,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
                                       TimeUnit unit) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
        if (command == null || unit == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
            throw new NullPointerException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
        RunnableScheduledFuture<?> t = decorateTask(command,
1007
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   524
            new ScheduledFutureTask<Void>(command, null,
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   525
                                          triggerTime(delay, unit)));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
        delayedExecute(t);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
        return t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
     * @throws RejectedExecutionException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
     * @throws NullPointerException       {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
    public <V> ScheduledFuture<V> schedule(Callable<V> callable,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
                                           long delay,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
                                           TimeUnit unit) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
        if (callable == null || unit == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
            throw new NullPointerException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
        RunnableScheduledFuture<V> t = decorateTask(callable,
1007
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   540
            new ScheduledFutureTask<V>(callable,
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   541
                                       triggerTime(delay, unit)));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
        delayedExecute(t);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
        return t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
     * @throws RejectedExecutionException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
     * @throws NullPointerException       {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
     * @throws IllegalArgumentException   {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
                                                  long initialDelay,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
                                                  long period,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
                                                  TimeUnit unit) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
        if (command == null || unit == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
            throw new NullPointerException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
        if (period <= 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
            throw new IllegalArgumentException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
        ScheduledFutureTask<Void> sft =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
            new ScheduledFutureTask<Void>(command,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
                                          null,
1007
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   562
                                          triggerTime(initialDelay, unit),
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
                                          unit.toNanos(period));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
        RunnableScheduledFuture<Void> t = decorateTask(command, sft);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
        sft.outerTask = t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
        delayedExecute(t);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
        return t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
     * @throws RejectedExecutionException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
     * @throws NullPointerException       {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
     * @throws IllegalArgumentException   {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
    public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
                                                     long initialDelay,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
                                                     long delay,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
                                                     TimeUnit unit) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
        if (command == null || unit == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
            throw new NullPointerException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
        if (delay <= 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
            throw new IllegalArgumentException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
        ScheduledFutureTask<Void> sft =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
            new ScheduledFutureTask<Void>(command,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
                                          null,
1007
72a8a27e1d69 6725789: ScheduledExecutorService does not work as expected in jdk7/6/5
dl
parents: 61
diff changeset
   586
                                          triggerTime(initialDelay, unit),
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
                                          unit.toNanos(-delay));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
        RunnableScheduledFuture<Void> t = decorateTask(command, sft);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
        sft.outerTask = t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
        delayedExecute(t);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
        return t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
     * Executes {@code command} with zero required delay.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
     * This has effect equivalent to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
     * {@link #schedule(Runnable,long,TimeUnit) schedule(command, 0, anyUnit)}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
     * Note that inspections of the queue and of the list returned by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
     * {@code shutdownNow} will access the zero-delayed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
     * {@link ScheduledFuture}, not the {@code command} itself.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
     * <p>A consequence of the use of {@code ScheduledFuture} objects is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
     * that {@link ThreadPoolExecutor#afterExecute afterExecute} is always
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
     * called with a null second {@code Throwable} argument, even if the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
     * {@code command} terminated abruptly.  Instead, the {@code Throwable}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
     * thrown by such a task can be obtained via {@link Future#get}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
     * @throws RejectedExecutionException at discretion of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
     *         {@code RejectedExecutionHandler}, if the task
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
     *         cannot be accepted for execution because the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
     *         executor has been shut down
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
     * @throws NullPointerException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
    public void execute(Runnable command) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
        schedule(command, 0, TimeUnit.NANOSECONDS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
    // Override AbstractExecutorService methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
     * @throws RejectedExecutionException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
     * @throws NullPointerException       {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
    public Future<?> submit(Runnable task) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
        return schedule(task, 0, TimeUnit.NANOSECONDS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
     * @throws RejectedExecutionException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
     * @throws NullPointerException       {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
    public <T> Future<T> submit(Runnable task, T result) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
        return schedule(Executors.callable(task, result),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
                        0, TimeUnit.NANOSECONDS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
     * @throws RejectedExecutionException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
     * @throws NullPointerException       {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
    public <T> Future<T> submit(Callable<T> task) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
        return schedule(task, 0, TimeUnit.NANOSECONDS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
     * Sets the policy on whether to continue executing existing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
     * periodic tasks even when this executor has been {@code shutdown}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
     * In this case, these tasks will only terminate upon
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
     * {@code shutdownNow} or after setting the policy to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
     * {@code false} when already shutdown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
     * This value is by default {@code false}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
     * @param value if {@code true}, continue after shutdown, else don't.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
     * @see #getContinueExistingPeriodicTasksAfterShutdownPolicy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
    public void setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
        continueExistingPeriodicTasksAfterShutdown = value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
        if (!value && isShutdown())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
            onShutdown();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
     * Gets the policy on whether to continue executing existing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
     * periodic tasks even when this executor has been {@code shutdown}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
     * In this case, these tasks will only terminate upon
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
     * {@code shutdownNow} or after setting the policy to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
     * {@code false} when already shutdown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
     * This value is by default {@code false}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
     * @return {@code true} if will continue after shutdown
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
     * @see #setContinueExistingPeriodicTasksAfterShutdownPolicy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
    public boolean getContinueExistingPeriodicTasksAfterShutdownPolicy() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
        return continueExistingPeriodicTasksAfterShutdown;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
     * Sets the policy on whether to execute existing delayed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
     * tasks even when this executor has been {@code shutdown}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
     * In this case, these tasks will only terminate upon
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
     * {@code shutdownNow}, or after setting the policy to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
     * {@code false} when already shutdown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
     * This value is by default {@code true}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
     * @param value if {@code true}, execute after shutdown, else don't.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
     * @see #getExecuteExistingDelayedTasksAfterShutdownPolicy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
    public void setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
        executeExistingDelayedTasksAfterShutdown = value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
        if (!value && isShutdown())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
            onShutdown();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
     * Gets the policy on whether to execute existing delayed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
     * tasks even when this executor has been {@code shutdown}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
     * In this case, these tasks will only terminate upon
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
     * {@code shutdownNow}, or after setting the policy to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
     * {@code false} when already shutdown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
     * This value is by default {@code true}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
     * @return {@code true} if will execute after shutdown
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
     * @see #setExecuteExistingDelayedTasksAfterShutdownPolicy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
    public boolean getExecuteExistingDelayedTasksAfterShutdownPolicy() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
        return executeExistingDelayedTasksAfterShutdown;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
    /**
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   710
     * 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
   711
     * 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
   712
     * by default {@code false}.
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   713
     *
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   714
     * @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
   715
     * @see #getRemoveOnCancelPolicy
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   716
     * @since 1.7
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
    public void setRemoveOnCancelPolicy(boolean value) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   719
        removeOnCancel = value;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   720
    }
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
    /**
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   723
     * 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
   724
     * 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
   725
     * by default {@code false}.
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
     * @return {@code true} if cancelled tasks are immediately removed
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   728
     *         from the queue
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   729
     * @see #setRemoveOnCancelPolicy
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   730
     * @since 1.7
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   731
     */
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   732
    public boolean getRemoveOnCancelPolicy() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   733
        return removeOnCancel;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   734
    }
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
    /**
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
     * 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
   738
     * 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
   739
     * 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
   740
     *
5691b03db1ea 6620549: ExecutorService#shutdown should clearly state that it does not block
martin
parents: 59
diff changeset
   741
     * <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
   742
     * complete execution.  Use {@link #awaitTermination awaitTermination}
5691b03db1ea 6620549: ExecutorService#shutdown should clearly state that it does not block
martin
parents: 59
diff changeset
   743
     * to do that.
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>If the {@code ExecuteExistingDelayedTasksAfterShutdownPolicy}
5691b03db1ea 6620549: ExecutorService#shutdown should clearly state that it does not block
martin
parents: 59
diff changeset
   746
     * 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
   747
     * 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
   748
     * ContinueExistingPeriodicTasksAfterShutdownPolicy} has been set
5691b03db1ea 6620549: ExecutorService#shutdown should clearly state that it does not block
martin
parents: 59
diff changeset
   749
     * {@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
   750
     * be cancelled.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
     * @throws SecurityException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
    public void shutdown() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
        super.shutdown();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
     * Attempts to stop all actively executing tasks, halts the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
     * processing of waiting tasks, and returns a list of the tasks
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
     * that were awaiting execution.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
     *
61
5691b03db1ea 6620549: ExecutorService#shutdown should clearly state that it does not block
martin
parents: 59
diff changeset
   763
     * <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
   764
     * terminate.  Use {@link #awaitTermination awaitTermination} to
5691b03db1ea 6620549: ExecutorService#shutdown should clearly state that it does not block
martin
parents: 59
diff changeset
   765
     * do that.
5691b03db1ea 6620549: ExecutorService#shutdown should clearly state that it does not block
martin
parents: 59
diff changeset
   766
     *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
     * <p>There are no guarantees beyond best-effort attempts to stop
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
     * processing actively executing tasks.  This implementation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
     * cancels tasks via {@link Thread#interrupt}, so any task that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
     * fails to respond to interrupts may never terminate.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
     * @return list of tasks that never commenced execution.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
     *         Each element of this list is a {@link ScheduledFuture},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
     *         including those tasks submitted using {@code execute},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
     *         which are for scheduling purposes used as the basis of a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
     *         zero-delay {@code ScheduledFuture}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
     * @throws SecurityException {@inheritDoc}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
    public List<Runnable> shutdownNow() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
        return super.shutdownNow();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
     * Returns the task queue used by this executor.  Each element of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
     * this queue is a {@link ScheduledFuture}, including those
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
     * tasks submitted using {@code execute} which are for scheduling
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
     * purposes used as the basis of a zero-delay
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
     * {@code ScheduledFuture}.  Iteration over this queue is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
     * <em>not</em> guaranteed to traverse tasks in the order in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
     * which they will execute.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
     * @return the task queue
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
    public BlockingQueue<Runnable> getQueue() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
        return super.getQueue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
    /**
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   799
     * Specialized delay queue. To mesh with TPE declarations, this
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   800
     * 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
   801
     * it can only hold RunnableScheduledFutures.
2
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
    static class DelayedWorkQueue extends AbstractQueue<Runnable>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
        implements BlockingQueue<Runnable> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   806
        /*
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   807
         * 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
   808
         * like those in DelayQueue and PriorityQueue, except that
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   809
         * every ScheduledFutureTask also records its index into the
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   810
         * 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
   811
         * cancellation, greatly speeding up removal (down from O(n)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   812
         * 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
   813
         * 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
   814
         * before clearing. But because the queue may also hold
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   815
         * RunnableScheduledFutures that are not ScheduledFutureTasks,
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   816
         * 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
   817
         * 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
   818
         * 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
   819
         * will be much more common.)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   820
         *
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   821
         * All heap operations must record index changes -- mainly
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   822
         * within siftUp and siftDown. Upon removal, a task's
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   823
         * heapIndex is set to -1. Note that ScheduledFutureTasks can
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   824
         * 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
   825
         * 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
   826
         * identified by heapIndex.
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   827
         */
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   828
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   829
        private static final int INITIAL_CAPACITY = 16;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   830
        private RunnableScheduledFuture[] queue =
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   831
            new RunnableScheduledFuture[INITIAL_CAPACITY];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   832
        private final ReentrantLock lock = new ReentrantLock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   833
        private int size = 0;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   834
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   835
        /**
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   836
         * 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
   837
         * queue.  This variant of the Leader-Follower pattern
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   838
         * (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
   839
         * minimize unnecessary timed waiting.  When a thread becomes
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   840
         * 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
   841
         * other threads await indefinitely.  The leader thread must
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   842
         * signal some other thread before returning from take() or
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   843
         * poll(...), unless some other thread becomes leader in the
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   844
         * 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
   845
         * 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
   846
         * invalidated by being reset to null, and some waiting
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   847
         * thread, but not necessarily the current leader, is
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   848
         * signalled.  So waiting threads must be prepared to acquire
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   849
         * and lose leadership while waiting.
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   850
         */
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   851
        private Thread leader = null;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   852
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   853
        /**
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   854
         * 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
   855
         * 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
   856
         */
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   857
        private final Condition available = lock.newCondition();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   858
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   859
        /**
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   860
         * Set f's heapIndex if it is a ScheduledFutureTask.
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   861
         */
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   862
        private void setIndex(RunnableScheduledFuture f, int idx) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   863
            if (f instanceof ScheduledFutureTask)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   864
                ((ScheduledFutureTask)f).heapIndex = idx;
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
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   867
        /**
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   868
         * 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
   869
         * Call only when holding lock.
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
        private void siftUp(int k, RunnableScheduledFuture key) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   872
            while (k > 0) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   873
                int parent = (k - 1) >>> 1;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   874
                RunnableScheduledFuture e = queue[parent];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   875
                if (key.compareTo(e) >= 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   876
                    break;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   877
                queue[k] = e;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   878
                setIndex(e, k);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   879
                k = parent;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   880
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   881
            queue[k] = key;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   882
            setIndex(key, k);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   883
        }
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
        /**
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   886
         * 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
   887
         * Call only when holding lock.
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
        private void siftDown(int k, RunnableScheduledFuture key) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   890
            int half = size >>> 1;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   891
            while (k < half) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   892
                int child = (k << 1) + 1;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   893
                RunnableScheduledFuture c = queue[child];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   894
                int right = child + 1;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   895
                if (right < size && c.compareTo(queue[right]) > 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   896
                    c = queue[child = right];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   897
                if (key.compareTo(c) <= 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   898
                    break;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   899
                queue[k] = c;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   900
                setIndex(c, k);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   901
                k = child;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   902
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   903
            queue[k] = key;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   904
            setIndex(key, k);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   905
        }
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
        /**
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   908
         * Resize the heap array.  Call only when holding lock.
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
        private void grow() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   911
            int oldCapacity = queue.length;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   912
            int newCapacity = oldCapacity + (oldCapacity >> 1); // grow 50%
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   913
            if (newCapacity < 0) // overflow
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   914
                newCapacity = Integer.MAX_VALUE;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   915
            queue = Arrays.copyOf(queue, newCapacity);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   916
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   917
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   918
        /**
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   919
         * Find index of given object, or -1 if absent
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
        private int indexOf(Object x) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   922
            if (x != null) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   923
                if (x instanceof ScheduledFutureTask) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   924
                    int i = ((ScheduledFutureTask) x).heapIndex;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   925
                    // Sanity check; x could conceivably be a
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   926
                    // ScheduledFutureTask from some other pool.
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   927
                    if (i >= 0 && i < size && queue[i] == x)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   928
                        return i;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   929
                } else {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   930
                    for (int i = 0; i < size; i++)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   931
                        if (x.equals(queue[i]))
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
                }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   934
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   935
            return -1;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   936
        }
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
        public boolean contains(Object x) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   939
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   940
            lock.lock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   941
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   942
                return indexOf(x) != -1;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   943
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   944
                lock.unlock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   945
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   946
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   947
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   948
        public boolean remove(Object x) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   949
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   950
            lock.lock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   951
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   952
                int i = indexOf(x);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   953
                if (i < 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   954
                    return false;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   955
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   956
                setIndex(queue[i], -1);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   957
                int s = --size;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   958
                RunnableScheduledFuture replacement = queue[s];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   959
                queue[s] = null;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   960
                if (s != i) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   961
                    siftDown(i, replacement);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   962
                    if (queue[i] == replacement)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   963
                        siftUp(i, replacement);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   964
                }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   965
                return true;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   966
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   967
                lock.unlock();
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
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   970
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   971
        public int size() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   972
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   973
            lock.lock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   974
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   975
                return size;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   976
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   977
                lock.unlock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   978
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   979
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   980
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   981
        public boolean isEmpty() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   982
            return size() == 0;
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 int remainingCapacity() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   986
            return Integer.MAX_VALUE;
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 RunnableScheduledFuture peek() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   990
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   991
            lock.lock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   992
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   993
                return queue[0];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   994
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   995
                lock.unlock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   996
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   997
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   998
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
   999
        public boolean offer(Runnable x) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1000
            if (x == null)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1001
                throw new NullPointerException();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1002
            RunnableScheduledFuture e = (RunnableScheduledFuture)x;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1003
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1004
            lock.lock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1005
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1006
                int i = size;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1007
                if (i >= queue.length)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1008
                    grow();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1009
                size = i + 1;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1010
                if (i == 0) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1011
                    queue[0] = e;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1012
                    setIndex(e, 0);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1013
                } else {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1014
                    siftUp(i, e);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1015
                }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1016
                if (queue[0] == e) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1017
                    leader = null;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1018
                    available.signal();
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
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1021
                lock.unlock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1022
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1023
            return true;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1024
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1025
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1026
        public void put(Runnable e) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1027
            offer(e);
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 boolean add(Runnable e) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1031
            return offer(e);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1034
        public boolean offer(Runnable e, long timeout, TimeUnit unit) {
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
        }
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1037
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1038
        /**
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1039
         * Performs common bookkeeping for poll and take: Replaces
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1040
         * 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
  1041
         * holding lock.
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1042
         * @param f the task to remove and return
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1043
         */
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1044
        private RunnableScheduledFuture finishPoll(RunnableScheduledFuture f) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1045
            int s = --size;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1046
            RunnableScheduledFuture x = queue[s];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1047
            queue[s] = null;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1048
            if (s != 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1049
                siftDown(0, x);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1050
            setIndex(f, -1);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1051
            return f;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1052
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1053
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1054
        public RunnableScheduledFuture poll() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1055
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1056
            lock.lock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1057
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1058
                RunnableScheduledFuture first = queue[0];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1059
                if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1060
                    return null;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1061
                else
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1062
                    return finishPoll(first);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1063
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1064
                lock.unlock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1065
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
        }
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1067
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1068
        public RunnableScheduledFuture take() throws InterruptedException {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1069
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1070
            lock.lockInterruptibly();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1071
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1072
                for (;;) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1073
                    RunnableScheduledFuture first = queue[0];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1074
                    if (first == null)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1075
                        available.await();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1076
                    else {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1077
                        long delay = first.getDelay(TimeUnit.NANOSECONDS);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1078
                        if (delay <= 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1079
                            return finishPoll(first);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1080
                        else if (leader != null)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1081
                            available.await();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1082
                        else {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1083
                            Thread thisThread = Thread.currentThread();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1084
                            leader = thisThread;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1085
                            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1086
                                available.awaitNanos(delay);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1087
                            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1088
                                if (leader == thisThread)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1089
                                    leader = null;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1090
                            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1091
                        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1092
                    }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1093
                }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1094
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1095
                if (leader == null && queue[0] != null)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1096
                    available.signal();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1097
                lock.unlock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1098
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
        }
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1100
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1101
        public RunnableScheduledFuture poll(long timeout, TimeUnit unit)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1102
            throws InterruptedException {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1103
            long nanos = unit.toNanos(timeout);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1104
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1105
            lock.lockInterruptibly();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1106
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1107
                for (;;) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1108
                    RunnableScheduledFuture first = queue[0];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1109
                    if (first == null) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1110
                        if (nanos <= 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1111
                            return null;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1112
                        else
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1113
                            nanos = available.awaitNanos(nanos);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1114
                    } else {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1115
                        long delay = first.getDelay(TimeUnit.NANOSECONDS);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1116
                        if (delay <= 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1117
                            return finishPoll(first);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1118
                        if (nanos <= 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1119
                            return null;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1120
                        if (nanos < delay || leader != null)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1121
                            nanos = available.awaitNanos(nanos);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1122
                        else {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1123
                            Thread thisThread = Thread.currentThread();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1124
                            leader = thisThread;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1125
                            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1126
                                long timeLeft = available.awaitNanos(delay);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1127
                                nanos -= delay - timeLeft;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1128
                            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1129
                                if (leader == thisThread)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1130
                                    leader = null;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1131
                            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1132
                        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1133
                    }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1134
                }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1135
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1136
                if (leader == null && queue[0] != null)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1137
                    available.signal();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1138
                lock.unlock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1139
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1142
        public void clear() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1143
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1144
            lock.lock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1145
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1146
                for (int i = 0; i < size; i++) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1147
                    RunnableScheduledFuture t = queue[i];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1148
                    if (t != null) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1149
                        queue[i] = null;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1150
                        setIndex(t, -1);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1151
                    }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1152
                }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1153
                size = 0;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1154
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1155
                lock.unlock();
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
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1158
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1159
        /**
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1160
         * 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
  1161
         * Used only by drainTo.  Call only when holding lock.
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
        private RunnableScheduledFuture pollExpired() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1164
            RunnableScheduledFuture first = queue[0];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1165
            if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1166
                return null;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1167
            return finishPoll(first);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1168
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1169
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1170
        public int drainTo(Collection<? super Runnable> c) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1171
            if (c == null)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1172
                throw new NullPointerException();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1173
            if (c == this)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1174
                throw new IllegalArgumentException();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1175
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1176
            lock.lock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1177
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1178
                RunnableScheduledFuture first;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1179
                int n = 0;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1180
                while ((first = pollExpired()) != null) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1181
                    c.add(first);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1182
                    ++n;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1183
                }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1184
                return n;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1185
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1186
                lock.unlock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1187
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1188
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1190
        public int drainTo(Collection<? super Runnable> c, int maxElements) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1191
            if (c == null)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1192
                throw new NullPointerException();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1193
            if (c == this)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1194
                throw new IllegalArgumentException();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1195
            if (maxElements <= 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1196
                return 0;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1197
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1198
            lock.lock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1199
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1200
                RunnableScheduledFuture first;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1201
                int n = 0;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1202
                while (n < maxElements && (first = pollExpired()) != null) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1203
                    c.add(first);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1204
                    ++n;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1205
                }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1206
                return n;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1207
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1208
                lock.unlock();
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
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1211
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1212
        public Object[] toArray() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1213
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1214
            lock.lock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1215
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1216
                return Arrays.copyOf(queue, size, Object[].class);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1217
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1218
                lock.unlock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1219
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1220
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1221
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1222
        @SuppressWarnings("unchecked")
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1223
        public <T> T[] toArray(T[] a) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1224
            final ReentrantLock lock = this.lock;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1225
            lock.lock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1226
            try {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1227
                if (a.length < size)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1228
                    return (T[]) Arrays.copyOf(queue, size, a.getClass());
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1229
                System.arraycopy(queue, 0, a, 0, size);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1230
                if (a.length > size)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1231
                    a[size] = null;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1232
                return a;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1233
            } finally {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1234
                lock.unlock();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1235
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1236
        }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1237
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1238
        public Iterator<Runnable> iterator() {
59
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1239
            return new Itr(Arrays.copyOf(queue, size));
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
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1242
        /**
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1243
         * 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
  1244
         */
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1245
        private class Itr implements Iterator<Runnable> {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1246
            final RunnableScheduledFuture[] array;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1247
            int cursor = 0;     // index of next element to return
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1248
            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
  1249
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1250
            Itr(RunnableScheduledFuture[] array) {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1251
                this.array = array;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1252
            }
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
            public boolean hasNext() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1255
                return cursor < array.length;
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 Runnable next() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1259
                if (cursor >= array.length)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1260
                    throw new NoSuchElementException();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1261
                lastRet = cursor;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1262
                return array[cursor++];
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1263
            }
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1264
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1265
            public void remove() {
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1266
                if (lastRet < 0)
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1267
                    throw new IllegalStateException();
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1268
                DelayedWorkQueue.this.remove(array[lastRet]);
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1269
                lastRet = -1;
f35c86a7e82d 6602600: Fast removal of cancelled scheduled thread pool tasks
martin
parents: 2
diff changeset
  1270
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1271
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1272
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1273
}