Source Code Cross Referenced for ScheduledThreadPoolExecutor.java in  » 6.0-JDK-Core » Collections-Jar-Zip-Logging-regex » java » util » concurrent » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » Collections Jar Zip Logging regex » java.util.concurrent 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001        /*
002         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
003         *
004         * This code is free software; you can redistribute it and/or modify it
005         * under the terms of the GNU General Public License version 2 only, as
006         * published by the Free Software Foundation.  Sun designates this
007         * particular file as subject to the "Classpath" exception as provided
008         * by Sun in the LICENSE file that accompanied this code.
009         *
010         * This code is distributed in the hope that it will be useful, but WITHOUT
011         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
012         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
013         * version 2 for more details (a copy is included in the LICENSE file that
014         * accompanied this code).
015         *
016         * You should have received a copy of the GNU General Public License version
017         * 2 along with this work; if not, write to the Free Software Foundation,
018         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
019         *
020         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
021         * CA 95054 USA or visit www.sun.com if you need additional information or
022         * have any questions.
023         */
024
025        /*
026         * This file is available under and governed by the GNU General Public
027         * License version 2 only, as published by the Free Software Foundation.
028         * However, the following notice accompanied the original version of this
029         * file:
030         *
031         * Written by Doug Lea with assistance from members of JCP JSR-166
032         * Expert Group and released to the public domain, as explained at
033         * http://creativecommons.org/licenses/publicdomain
034         */
035
036        package java.util.concurrent;
037
038        import java.util.concurrent.atomic.*;
039        import java.util.*;
040
041        /**
042         * A {@link ThreadPoolExecutor} that can additionally schedule
043         * commands to run after a given delay, or to execute
044         * periodically. This class is preferable to {@link java.util.Timer}
045         * when multiple worker threads are needed, or when the additional
046         * flexibility or capabilities of {@link ThreadPoolExecutor} (which
047         * this class extends) are required.
048         *
049         * <p> Delayed tasks execute no sooner than they are enabled, but
050         * without any real-time guarantees about when, after they are
051         * enabled, they will commence. Tasks scheduled for exactly the same
052         * execution time are enabled in first-in-first-out (FIFO) order of
053         * submission.
054         *
055         * <p>While this class inherits from {@link ThreadPoolExecutor}, a few
056         * of the inherited tuning methods are not useful for it. In
057         * particular, because it acts as a fixed-sized pool using
058         * {@code corePoolSize} threads and an unbounded queue, adjustments
059         * to {@code maximumPoolSize} have no useful effect. Additionally, it
060         * is almost never a good idea to set {@code corePoolSize} to zero or
061         * use {@code allowCoreThreadTimeOut} because this may leave the pool
062         * without threads to handle tasks once they become eligible to run.
063         *
064         * <p><b>Extension notes:</b> This class overrides the
065         * {@link ThreadPoolExecutor#execute execute} and
066         * {@link AbstractExecutorService#submit(Runnable) submit}
067         * methods to generate internal {@link ScheduledFuture} objects to
068         * control per-task delays and scheduling.  To preserve
069         * functionality, any further overrides of these methods in
070         * subclasses must invoke superclass versions, which effectively
071         * disables additional task customization.  However, this class
072         * provides alternative protected extension method
073         * {@code decorateTask} (one version each for {@code Runnable} and
074         * {@code Callable}) that can be used to customize the concrete task
075         * types used to execute commands entered via {@code execute},
076         * {@code submit}, {@code schedule}, {@code scheduleAtFixedRate},
077         * and {@code scheduleWithFixedDelay}.  By default, a
078         * {@code ScheduledThreadPoolExecutor} uses a task type extending
079         * {@link FutureTask}. However, this may be modified or replaced using
080         * subclasses of the form:
081         *
082         *  <pre> {@code
083         * public class CustomScheduledExecutor extends ScheduledThreadPoolExecutor {
084         *
085         *   static class CustomTask<V> implements RunnableScheduledFuture<V> { ... }
086         *
087         *   protected <V> RunnableScheduledFuture<V> decorateTask(
088         *                Runnable r, RunnableScheduledFuture<V> task) {
089         *       return new CustomTask<V>(r, task);
090         *   }
091         *
092         *   protected <V> RunnableScheduledFuture<V> decorateTask(
093         *                Callable<V> c, RunnableScheduledFuture<V> task) {
094         *       return new CustomTask<V>(c, task);
095         *   }
096         *   // ... add constructors, etc.
097         * }}</pre>
098         *
099         * @since 1.5
100         * @author Doug Lea
101         */
102        public class ScheduledThreadPoolExecutor extends ThreadPoolExecutor
103                implements  ScheduledExecutorService {
104
105            /*
106             * This class specializes ThreadPoolExecutor implementation by
107             *
108             * 1. Using a custom task type, ScheduledFutureTask for
109             *    tasks, even those that don't require scheduling (i.e.,
110             *    those submitted using ExecutorService execute, not
111             *    ScheduledExecutorService methods) which are treated as
112             *    delayed tasks with a delay of zero.
113             *
114             * 2. Using a custom queue (DelayedWorkQueue) based on an
115             *    unbounded DelayQueue. The lack of capacity constraint and
116             *    the fact that corePoolSize and maximumPoolSize are
117             *    effectively identical simplifies some execution mechanics
118             *    (see delayedExecute) compared to ThreadPoolExecutor
119             *    version.
120             *
121             *    The DelayedWorkQueue class is defined below for the sake of
122             *    ensuring that all elements are instances of
123             *    RunnableScheduledFuture.  Since DelayQueue otherwise
124             *    requires type be Delayed, but not necessarily Runnable, and
125             *    the workQueue requires the opposite, we need to explicitly
126             *    define a class that requires both to ensure that users don't
127             *    add objects that aren't RunnableScheduledFutures via
128             *    getQueue().add() etc.
129             *
130             * 3. Supporting optional run-after-shutdown parameters, which
131             *    leads to overrides of shutdown methods to remove and cancel
132             *    tasks that should NOT be run after shutdown, as well as
133             *    different recheck logic when task (re)submission overlaps
134             *    with a shutdown.
135             *
136             * 4. Task decoration methods to allow interception and
137             *    instrumentation, which are needed because subclasses cannot
138             *    otherwise override submit methods to get this effect. These
139             *    don't have any impact on pool control logic though.
140             */
141
142            /**
143             * False if should cancel/suppress periodic tasks on shutdown.
144             */
145            private volatile boolean continueExistingPeriodicTasksAfterShutdown;
146
147            /**
148             * False if should cancel non-periodic tasks on shutdown.
149             */
150            private volatile boolean executeExistingDelayedTasksAfterShutdown = true;
151
152            /**
153             * Sequence number to break scheduling ties, and in turn to
154             * guarantee FIFO order among tied entries.
155             */
156            private static final AtomicLong sequencer = new AtomicLong(0);
157
158            /**
159             * Returns current nanosecond time.
160             */
161            final long now() {
162                return System.nanoTime();
163            }
164
165            private class ScheduledFutureTask<V> extends FutureTask<V>
166                    implements  RunnableScheduledFuture<V> {
167
168                /** Sequence number to break ties FIFO */
169                private final long sequenceNumber;
170                /** The time the task is enabled to execute in nanoTime units */
171                private long time;
172                /**
173                 * Period in nanoseconds for repeating tasks.  A positive
174                 * value indicates fixed-rate execution.  A negative value
175                 * indicates fixed-delay execution.  A value of 0 indicates a
176                 * non-repeating task.
177                 */
178                private final long period;
179
180                /** The actual task to be re-enqueued by reExecutePeriodic */
181                RunnableScheduledFuture<V> outerTask = this ;
182
183                /**
184                 * Creates a one-shot action with given nanoTime-based trigger time.
185                 */
186                ScheduledFutureTask(Runnable r, V result, long ns) {
187                    super (r, result);
188                    this .time = ns;
189                    this .period = 0;
190                    this .sequenceNumber = sequencer.getAndIncrement();
191                }
192
193                /**
194                 * Creates a periodic action with given nano time and period.
195                 */
196                ScheduledFutureTask(Runnable r, V result, long ns, long period) {
197                    super (r, result);
198                    this .time = ns;
199                    this .period = period;
200                    this .sequenceNumber = sequencer.getAndIncrement();
201                }
202
203                /**
204                 * Creates a one-shot action with given nanoTime-based trigger.
205                 */
206                ScheduledFutureTask(Callable<V> callable, long ns) {
207                    super (callable);
208                    this .time = ns;
209                    this .period = 0;
210                    this .sequenceNumber = sequencer.getAndIncrement();
211                }
212
213                public long getDelay(TimeUnit unit) {
214                    long d = unit.convert(time - now(), TimeUnit.NANOSECONDS);
215                    return d;
216                }
217
218                public int compareTo(Delayed other) {
219                    if (other == this ) // compare zero ONLY if same object
220                        return 0;
221                    if (other instanceof  ScheduledFutureTask) {
222                        ScheduledFutureTask<?> x = (ScheduledFutureTask<?>) other;
223                        long diff = time - x.time;
224                        if (diff < 0)
225                            return -1;
226                        else if (diff > 0)
227                            return 1;
228                        else if (sequenceNumber < x.sequenceNumber)
229                            return -1;
230                        else
231                            return 1;
232                    }
233                    long d = (getDelay(TimeUnit.NANOSECONDS) - other
234                            .getDelay(TimeUnit.NANOSECONDS));
235                    return (d == 0) ? 0 : ((d < 0) ? -1 : 1);
236                }
237
238                /**
239                 * Returns true if this is a periodic (not a one-shot) action.
240                 *
241                 * @return true if periodic
242                 */
243                public boolean isPeriodic() {
244                    return period != 0;
245                }
246
247                /**
248                 * Sets the next time to run for a periodic task.
249                 */
250                private void setNextRunTime() {
251                    long p = period;
252                    if (p > 0)
253                        time += p;
254                    else
255                        time = now() - p;
256                }
257
258                /**
259                 * Overrides FutureTask version so as to reset/requeue if periodic.
260                 */
261                public void run() {
262                    boolean periodic = isPeriodic();
263                    if (!canRunInCurrentRunState(periodic))
264                        cancel(false);
265                    else if (!periodic)
266                        ScheduledFutureTask.super .run();
267                    else if (ScheduledFutureTask.super .runAndReset()) {
268                        setNextRunTime();
269                        reExecutePeriodic(outerTask);
270                    }
271                }
272            }
273
274            /**
275             * Returns true if can run a task given current run state
276             * and run-after-shutdown parameters.
277             *
278             * @param periodic true if this task periodic, false if delayed
279             */
280            boolean canRunInCurrentRunState(boolean periodic) {
281                return isRunningOrShutdown(periodic ? continueExistingPeriodicTasksAfterShutdown
282                        : executeExistingDelayedTasksAfterShutdown);
283            }
284
285            /**
286             * Main execution method for delayed or periodic tasks.  If pool
287             * is shut down, rejects the task. Otherwise adds task to queue
288             * and starts a thread, if necessary, to run it.  (We cannot
289             * prestart the thread to run the task because the task (probably)
290             * shouldn't be run yet,) If the pool is shut down while the task
291             * is being added, cancel and remove it if required by state and
292             * run-after-shutdown parameters.
293             *
294             * @param task the task
295             */
296            private void delayedExecute(RunnableScheduledFuture<?> task) {
297                if (isShutdown())
298                    reject(task);
299                else {
300                    super .getQueue().add(task);
301                    if (isShutdown()
302                            && !canRunInCurrentRunState(task.isPeriodic())
303                            && remove(task))
304                        task.cancel(false);
305                    else
306                        prestartCoreThread();
307                }
308            }
309
310            /**
311             * Requeues a periodic task unless current run state precludes it.
312             * Same idea as delayedExecute except drops task rather than rejecting.
313             *
314             * @param task the task
315             */
316            void reExecutePeriodic(RunnableScheduledFuture<?> task) {
317                if (canRunInCurrentRunState(true)) {
318                    super .getQueue().add(task);
319                    if (!canRunInCurrentRunState(true) && remove(task))
320                        task.cancel(false);
321                    else
322                        prestartCoreThread();
323                }
324            }
325
326            /**
327             * Cancels and clears the queue of all tasks that should not be run
328             * due to shutdown policy.  Invoked within super.shutdown.
329             */
330            @Override
331            void onShutdown() {
332                BlockingQueue<Runnable> q = super .getQueue();
333                boolean keepDelayed = getExecuteExistingDelayedTasksAfterShutdownPolicy();
334                boolean keepPeriodic = getContinueExistingPeriodicTasksAfterShutdownPolicy();
335                if (!keepDelayed && !keepPeriodic)
336                    q.clear();
337                else {
338                    // Traverse snapshot to avoid iterator exceptions
339                    for (Object e : q.toArray()) {
340                        if (e instanceof  RunnableScheduledFuture) {
341                            RunnableScheduledFuture<?> t = (RunnableScheduledFuture<?>) e;
342                            if ((t.isPeriodic() ? !keepPeriodic : !keepDelayed)
343                                    || t.isCancelled()) { // also remove if already cancelled
344                                if (q.remove(t))
345                                    t.cancel(false);
346                            }
347                        }
348                    }
349                }
350                tryTerminate();
351            }
352
353            /**
354             * Modifies or replaces the task used to execute a runnable.
355             * This method can be used to override the concrete
356             * class used for managing internal tasks.
357             * The default implementation simply returns the given task.
358             *
359             * @param runnable the submitted Runnable
360             * @param task the task created to execute the runnable
361             * @return a task that can execute the runnable
362             * @since 1.6
363             */
364            protected <V> RunnableScheduledFuture<V> decorateTask(
365                    Runnable runnable, RunnableScheduledFuture<V> task) {
366                return task;
367            }
368
369            /**
370             * Modifies or replaces the task used to execute a callable.
371             * This method can be used to override the concrete
372             * class used for managing internal tasks.
373             * The default implementation simply returns the given task.
374             *
375             * @param callable the submitted Callable
376             * @param task the task created to execute the callable
377             * @return a task that can execute the callable
378             * @since 1.6
379             */
380            protected <V> RunnableScheduledFuture<V> decorateTask(
381                    Callable<V> callable, RunnableScheduledFuture<V> task) {
382                return task;
383            }
384
385            /**
386             * Creates a new {@code ScheduledThreadPoolExecutor} with the
387             * given core pool size.
388             *
389             * @param corePoolSize the number of threads to keep in the pool, even
390             *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
391             * @throws IllegalArgumentException if {@code corePoolSize < 0}
392             */
393            public ScheduledThreadPoolExecutor(int corePoolSize) {
394                super (corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
395                        new DelayedWorkQueue());
396            }
397
398            /**
399             * Creates a new {@code ScheduledThreadPoolExecutor} with the
400             * given initial parameters.
401             *
402             * @param corePoolSize the number of threads to keep in the pool, even
403             *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
404             * @param threadFactory the factory to use when the executor
405             *        creates a new thread
406             * @throws IllegalArgumentException if {@code corePoolSize < 0}
407             * @throws NullPointerException if {@code threadFactory} is null
408             */
409            public ScheduledThreadPoolExecutor(int corePoolSize,
410                    ThreadFactory threadFactory) {
411                super (corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
412                        new DelayedWorkQueue(), threadFactory);
413            }
414
415            /**
416             * Creates a new ScheduledThreadPoolExecutor with the given
417             * initial parameters.
418             *
419             * @param corePoolSize the number of threads to keep in the pool, even
420             *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
421             * @param handler the handler to use when execution is blocked
422             *        because the thread bounds and queue capacities are reached
423             * @throws IllegalArgumentException if {@code corePoolSize < 0}
424             * @throws NullPointerException if {@code handler} is null
425             */
426            public ScheduledThreadPoolExecutor(int corePoolSize,
427                    RejectedExecutionHandler handler) {
428                super (corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
429                        new DelayedWorkQueue(), handler);
430            }
431
432            /**
433             * Creates a new ScheduledThreadPoolExecutor with the given
434             * initial parameters.
435             *
436             * @param corePoolSize the number of threads to keep in the pool, even
437             *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
438             * @param threadFactory the factory to use when the executor
439             *        creates a new thread
440             * @param handler the handler to use when execution is blocked
441             *        because the thread bounds and queue capacities are reached
442             * @throws IllegalArgumentException if {@code corePoolSize < 0}
443             * @throws NullPointerException if {@code threadFactory} or
444             *         {@code handler} is null
445             */
446            public ScheduledThreadPoolExecutor(int corePoolSize,
447                    ThreadFactory threadFactory,
448                    RejectedExecutionHandler handler) {
449                super (corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
450                        new DelayedWorkQueue(), threadFactory, handler);
451            }
452
453            /**
454             * @throws RejectedExecutionException {@inheritDoc}
455             * @throws NullPointerException       {@inheritDoc}
456             */
457            public ScheduledFuture<?> schedule(Runnable command, long delay,
458                    TimeUnit unit) {
459                if (command == null || unit == null)
460                    throw new NullPointerException();
461                if (delay < 0)
462                    delay = 0;
463                long triggerTime = now() + unit.toNanos(delay);
464                RunnableScheduledFuture<?> t = decorateTask(command,
465                        new ScheduledFutureTask<Void>(command, null,
466                                triggerTime));
467                delayedExecute(t);
468                return t;
469            }
470
471            /**
472             * @throws RejectedExecutionException {@inheritDoc}
473             * @throws NullPointerException       {@inheritDoc}
474             */
475            public <V> ScheduledFuture<V> schedule(Callable<V> callable,
476                    long delay, TimeUnit unit) {
477                if (callable == null || unit == null)
478                    throw new NullPointerException();
479                if (delay < 0)
480                    delay = 0;
481                long triggerTime = now() + unit.toNanos(delay);
482                RunnableScheduledFuture<V> t = decorateTask(callable,
483                        new ScheduledFutureTask<V>(callable, triggerTime));
484                delayedExecute(t);
485                return t;
486            }
487
488            /**
489             * @throws RejectedExecutionException {@inheritDoc}
490             * @throws NullPointerException       {@inheritDoc}
491             * @throws IllegalArgumentException   {@inheritDoc}
492             */
493            public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
494                    long initialDelay, long period, TimeUnit unit) {
495                if (command == null || unit == null)
496                    throw new NullPointerException();
497                if (period <= 0)
498                    throw new IllegalArgumentException();
499                if (initialDelay < 0)
500                    initialDelay = 0;
501                long triggerTime = now() + unit.toNanos(initialDelay);
502                ScheduledFutureTask<Void> sft = new ScheduledFutureTask<Void>(
503                        command, null, triggerTime, unit.toNanos(period));
504                RunnableScheduledFuture<Void> t = decorateTask(command, sft);
505                sft.outerTask = t;
506                delayedExecute(t);
507                return t;
508            }
509
510            /**
511             * @throws RejectedExecutionException {@inheritDoc}
512             * @throws NullPointerException       {@inheritDoc}
513             * @throws IllegalArgumentException   {@inheritDoc}
514             */
515            public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
516                    long initialDelay, long delay, TimeUnit unit) {
517                if (command == null || unit == null)
518                    throw new NullPointerException();
519                if (delay <= 0)
520                    throw new IllegalArgumentException();
521                if (initialDelay < 0)
522                    initialDelay = 0;
523                long triggerTime = now() + unit.toNanos(initialDelay);
524                ScheduledFutureTask<Void> sft = new ScheduledFutureTask<Void>(
525                        command, null, triggerTime, unit.toNanos(-delay));
526                RunnableScheduledFuture<Void> t = decorateTask(command, sft);
527                sft.outerTask = t;
528                delayedExecute(t);
529                return t;
530            }
531
532            /**
533             * Executes {@code command} with zero required delay.
534             * This has effect equivalent to
535             * {@link #schedule(Runnable,long,TimeUnit) schedule(command, 0, anyUnit)}.
536             * Note that inspections of the queue and of the list returned by
537             * {@code shutdownNow} will access the zero-delayed
538             * {@link ScheduledFuture}, not the {@code command} itself.
539             *
540             * <p>A consequence of the use of {@code ScheduledFuture} objects is
541             * that {@link ThreadPoolExecutor#afterExecute afterExecute} is always
542             * called with a null second {@code Throwable} argument, even if the
543             * {@code command} terminated abruptly.  Instead, the {@code Throwable}
544             * thrown by such a task can be obtained via {@link Future#get}.
545             *
546             * @throws RejectedExecutionException at discretion of
547             *         {@code RejectedExecutionHandler}, if the task
548             *         cannot be accepted for execution because the
549             *         executor has been shut down
550             * @throws NullPointerException {@inheritDoc}
551             */
552            public void execute(Runnable command) {
553                schedule(command, 0, TimeUnit.NANOSECONDS);
554            }
555
556            // Override AbstractExecutorService methods
557
558            /**
559             * @throws RejectedExecutionException {@inheritDoc}
560             * @throws NullPointerException       {@inheritDoc}
561             */
562            public Future<?> submit(Runnable task) {
563                return schedule(task, 0, TimeUnit.NANOSECONDS);
564            }
565
566            /**
567             * @throws RejectedExecutionException {@inheritDoc}
568             * @throws NullPointerException       {@inheritDoc}
569             */
570            public <T> Future<T> submit(Runnable task, T result) {
571                return schedule(Executors.callable(task, result), 0,
572                        TimeUnit.NANOSECONDS);
573            }
574
575            /**
576             * @throws RejectedExecutionException {@inheritDoc}
577             * @throws NullPointerException       {@inheritDoc}
578             */
579            public <T> Future<T> submit(Callable<T> task) {
580                return schedule(task, 0, TimeUnit.NANOSECONDS);
581            }
582
583            /**
584             * Sets the policy on whether to continue executing existing
585             * periodic tasks even when this executor has been {@code shutdown}.
586             * In this case, these tasks will only terminate upon
587             * {@code shutdownNow} or after setting the policy to
588             * {@code false} when already shutdown.
589             * This value is by default {@code false}.
590             *
591             * @param value if {@code true}, continue after shutdown, else don't.
592             * @see #getContinueExistingPeriodicTasksAfterShutdownPolicy
593             */
594            public void setContinueExistingPeriodicTasksAfterShutdownPolicy(
595                    boolean value) {
596                continueExistingPeriodicTasksAfterShutdown = value;
597                if (!value && isShutdown())
598                    onShutdown();
599            }
600
601            /**
602             * Gets the policy on whether to continue executing existing
603             * periodic tasks even when this executor has been {@code shutdown}.
604             * In this case, these tasks will only terminate upon
605             * {@code shutdownNow} or after setting the policy to
606             * {@code false} when already shutdown.
607             * This value is by default {@code false}.
608             *
609             * @return {@code true} if will continue after shutdown
610             * @see #setContinueExistingPeriodicTasksAfterShutdownPolicy
611             */
612            public boolean getContinueExistingPeriodicTasksAfterShutdownPolicy() {
613                return continueExistingPeriodicTasksAfterShutdown;
614            }
615
616            /**
617             * Sets the policy on whether to execute existing delayed
618             * tasks even when this executor has been {@code shutdown}.
619             * In this case, these tasks will only terminate upon
620             * {@code shutdownNow}, or after setting the policy to
621             * {@code false} when already shutdown.
622             * This value is by default {@code true}.
623             *
624             * @param value if {@code true}, execute after shutdown, else don't.
625             * @see #getExecuteExistingDelayedTasksAfterShutdownPolicy
626             */
627            public void setExecuteExistingDelayedTasksAfterShutdownPolicy(
628                    boolean value) {
629                executeExistingDelayedTasksAfterShutdown = value;
630                if (!value && isShutdown())
631                    onShutdown();
632            }
633
634            /**
635             * Gets the policy on whether to execute existing delayed
636             * tasks even when this executor has been {@code shutdown}.
637             * In this case, these tasks will only terminate upon
638             * {@code shutdownNow}, or after setting the policy to
639             * {@code false} when already shutdown.
640             * This value is by default {@code true}.
641             *
642             * @return {@code true} if will execute after shutdown
643             * @see #setExecuteExistingDelayedTasksAfterShutdownPolicy
644             */
645            public boolean getExecuteExistingDelayedTasksAfterShutdownPolicy() {
646                return executeExistingDelayedTasksAfterShutdown;
647            }
648
649            /**
650             * Initiates an orderly shutdown in which previously submitted
651             * tasks are executed, but no new tasks will be accepted.  If the
652             * {@code ExecuteExistingDelayedTasksAfterShutdownPolicy} has
653             * been set {@code false}, existing delayed tasks whose delays
654             * have not yet elapsed are cancelled.  And unless the
655             * {@code ContinueExistingPeriodicTasksAfterShutdownPolicy} has
656             * been set {@code true}, future executions of existing periodic
657             * tasks will be cancelled.
658             *
659             * @throws SecurityException {@inheritDoc}
660             */
661            public void shutdown() {
662                super .shutdown();
663            }
664
665            /**
666             * Attempts to stop all actively executing tasks, halts the
667             * processing of waiting tasks, and returns a list of the tasks
668             * that were awaiting execution.
669             *
670             * <p>There are no guarantees beyond best-effort attempts to stop
671             * processing actively executing tasks.  This implementation
672             * cancels tasks via {@link Thread#interrupt}, so any task that
673             * fails to respond to interrupts may never terminate.
674             *
675             * @return list of tasks that never commenced execution.
676             *         Each element of this list is a {@link ScheduledFuture},
677             *         including those tasks submitted using {@code execute},
678             *         which are for scheduling purposes used as the basis of a
679             *         zero-delay {@code ScheduledFuture}.
680             * @throws SecurityException {@inheritDoc}
681             */
682            public List<Runnable> shutdownNow() {
683                return super .shutdownNow();
684            }
685
686            /**
687             * Returns the task queue used by this executor.  Each element of
688             * this queue is a {@link ScheduledFuture}, including those
689             * tasks submitted using {@code execute} which are for scheduling
690             * purposes used as the basis of a zero-delay
691             * {@code ScheduledFuture}.  Iteration over this queue is
692             * <em>not</em> guaranteed to traverse tasks in the order in
693             * which they will execute.
694             *
695             * @return the task queue
696             */
697            public BlockingQueue<Runnable> getQueue() {
698                return super .getQueue();
699            }
700
701            /**
702             * An annoying wrapper class to convince javac to use a
703             * DelayQueue<RunnableScheduledFuture> as a BlockingQueue<Runnable>
704             */
705            private static class DelayedWorkQueue extends
706                    AbstractCollection<Runnable> implements 
707                    BlockingQueue<Runnable> {
708
709                private final DelayQueue<RunnableScheduledFuture> dq = new DelayQueue<RunnableScheduledFuture>();
710
711                public Runnable poll() {
712                    return dq.poll();
713                }
714
715                public Runnable peek() {
716                    return dq.peek();
717                }
718
719                public Runnable take() throws InterruptedException {
720                    return dq.take();
721                }
722
723                public Runnable poll(long timeout, TimeUnit unit)
724                        throws InterruptedException {
725                    return dq.poll(timeout, unit);
726                }
727
728                public boolean add(Runnable x) {
729                    return dq.add((RunnableScheduledFuture) x);
730                }
731
732                public boolean offer(Runnable x) {
733                    return dq.offer((RunnableScheduledFuture) x);
734                }
735
736                public void put(Runnable x) {
737                    dq.put((RunnableScheduledFuture) x);
738                }
739
740                public boolean offer(Runnable x, long timeout, TimeUnit unit) {
741                    return dq.offer((RunnableScheduledFuture) x, timeout, unit);
742                }
743
744                public Runnable remove() {
745                    return dq.remove();
746                }
747
748                public Runnable element() {
749                    return dq.element();
750                }
751
752                public void clear() {
753                    dq.clear();
754                }
755
756                public int drainTo(Collection<? super  Runnable> c) {
757                    return dq.drainTo(c);
758                }
759
760                public int drainTo(Collection<? super  Runnable> c,
761                        int maxElements) {
762                    return dq.drainTo(c, maxElements);
763                }
764
765                public int remainingCapacity() {
766                    return dq.remainingCapacity();
767                }
768
769                public boolean remove(Object x) {
770                    return dq.remove(x);
771                }
772
773                public boolean contains(Object x) {
774                    return dq.contains(x);
775                }
776
777                public int size() {
778                    return dq.size();
779                }
780
781                public boolean isEmpty() {
782                    return dq.isEmpty();
783                }
784
785                public Object[] toArray() {
786                    return dq.toArray();
787                }
788
789                public <T> T[] toArray(T[] array) {
790                    return dq.toArray(array);
791                }
792
793                public Iterator<Runnable> iterator() {
794                    return new Iterator<Runnable>() {
795                        private Iterator<RunnableScheduledFuture> it = dq
796                                .iterator();
797
798                        public boolean hasNext() {
799                            return it.hasNext();
800                        }
801
802                        public Runnable next() {
803                            return it.next();
804                        }
805
806                        public void remove() {
807                            it.remove();
808                        }
809                    };
810                }
811            }
812        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.