KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > util > concurrent > ThreadPoolExecutor


1 /*
2  * @(#)ThreadPoolExecutor.java 1.9 04/07/12
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.util.concurrent;
9 import java.util.concurrent.locks.*;
10 import java.util.*;
11
12 /**
13  * An {@link ExecutorService} that executes each submitted task using
14  * one of possibly several pooled threads, normally configured
15  * using {@link Executors} factory methods.
16  *
17  * <p>Thread pools address two different problems: they usually
18  * provide improved performance when executing large numbers of
19  * asynchronous tasks, due to reduced per-task invocation overhead,
20  * and they provide a means of bounding and managing the resources,
21  * including threads, consumed when executing a collection of tasks.
22  * Each <tt>ThreadPoolExecutor</tt> also maintains some basic
23  * statistics, such as the number of completed tasks.
24  *
25  * <p>To be useful across a wide range of contexts, this class
26  * provides many adjustable parameters and extensibility
27  * hooks. However, programmers are urged to use the more convenient
28  * {@link Executors} factory methods {@link
29  * Executors#newCachedThreadPool} (unbounded thread pool, with
30  * automatic thread reclamation), {@link Executors#newFixedThreadPool}
31  * (fixed size thread pool) and {@link
32  * Executors#newSingleThreadExecutor} (single background thread), that
33  * preconfigure settings for the most common usage
34  * scenarios. Otherwise, use the following guide when manually
35  * configuring and tuning this class:
36  *
37  * <dl>
38  *
39  * <dt>Core and maximum pool sizes</dt>
40  *
41  * <dd>A <tt>ThreadPoolExecutor</tt> will automatically adjust the
42  * pool size
43  * (see {@link ThreadPoolExecutor#getPoolSize})
44  * according to the bounds set by corePoolSize
45  * (see {@link ThreadPoolExecutor#getCorePoolSize})
46  * and
47  * maximumPoolSize
48  * (see {@link ThreadPoolExecutor#getMaximumPoolSize}).
49  * When a new task is submitted in method {@link
50  * ThreadPoolExecutor#execute}, and fewer than corePoolSize threads
51  * are running, a new thread is created to handle the request, even if
52  * other worker threads are idle. If there are more than
53  * corePoolSize but less than maximumPoolSize threads running, a new
54  * thread will be created only if the queue is full. By setting
55  * corePoolSize and maximumPoolSize the same, you create a fixed-size
56  * thread pool. By setting maximumPoolSize to an essentially unbounded
57  * value such as <tt>Integer.MAX_VALUE</tt>, you allow the pool to
58  * accommodate an arbitrary number of concurrent tasks. Most typically,
59  * core and maximum pool sizes are set only upon construction, but they
60  * may also be changed dynamically using {@link
61  * ThreadPoolExecutor#setCorePoolSize} and {@link
62  * ThreadPoolExecutor#setMaximumPoolSize}. <dd>
63  *
64  * <dt> On-demand construction
65  *
66  * <dd> By default, even core threads are initially created and
67  * started only when needed by new tasks, but this can be overridden
68  * dynamically using method {@link
69  * ThreadPoolExecutor#prestartCoreThread} or
70  * {@link ThreadPoolExecutor#prestartAllCoreThreads}. </dd>
71  *
72  * <dt>Creating new threads</dt>
73  *
74  * <dd>New threads are created using a {@link
75  * java.util.concurrent.ThreadFactory}. If not otherwise specified, a
76  * {@link Executors#defaultThreadFactory} is used, that creates threads to all
77  * be in the same {@link ThreadGroup} and with the same
78  * <tt>NORM_PRIORITY</tt> priority and non-daemon status. By supplying
79  * a different ThreadFactory, you can alter the thread's name, thread
80  * group, priority, daemon status, etc. If a <tt>ThreadFactory</tt> fails to create
81  * a thread when asked by returning null from <tt>newThread</tt>,
82  * the executor will continue, but might
83  * not be able to execute any tasks. </dd>
84  *
85  * <dt>Keep-alive times</dt>
86  *
87  * <dd>If the pool currently has more than corePoolSize threads,
88  * excess threads will be terminated if they have been idle for more
89  * than the keepAliveTime (see {@link
90  * ThreadPoolExecutor#getKeepAliveTime}). This provides a means of
91  * reducing resource consumption when the pool is not being actively
92  * used. If the pool becomes more active later, new threads will be
93  * constructed. This parameter can also be changed dynamically
94  * using method {@link ThreadPoolExecutor#setKeepAliveTime}. Using
95  * a value of <tt>Long.MAX_VALUE</tt> {@link TimeUnit#NANOSECONDS}
96  * effectively disables idle threads from ever terminating prior
97  * to shut down.
98  * </dd>
99  *
100  * <dt>Queuing</dt>
101  *
102  * <dd>Any {@link BlockingQueue} may be used to transfer and hold
103  * submitted tasks. The use of this queue interacts with pool sizing:
104  *
105  * <ul>
106  *
107  * <li> If fewer than corePoolSize threads are running, the Executor
108  * always prefers adding a new thread
109  * rather than queuing.</li>
110  *
111  * <li> If corePoolSize or more threads are running, the Executor
112  * always prefers queuing a request rather than adding a new
113  * thread.</li>
114  *
115  * <li> If a request cannot be queued, a new thread is created unless
116  * this would exceed maximumPoolSize, in which case, the task will be
117  * rejected.</li>
118  *
119  * </ul>
120  *
121  * There are three general strategies for queuing:
122  * <ol>
123  *
124  * <li> <em> Direct handoffs.</em> A good default choice for a work
125  * queue is a {@link SynchronousQueue} that hands off tasks to threads
126  * without otherwise holding them. Here, an attempt to queue a task
127  * will fail if no threads are immediately available to run it, so a
128  * new thread will be constructed. This policy avoids lockups when
129  * handling sets of requests that might have internal dependencies.
130  * Direct handoffs generally require unbounded maximumPoolSizes to
131  * avoid rejection of new submitted tasks. This in turn admits the
132  * possibility of unbounded thread growth when commands continue to
133  * arrive on average faster than they can be processed. </li>
134  *
135  * <li><em> Unbounded queues.</em> Using an unbounded queue (for
136  * example a {@link LinkedBlockingQueue} without a predefined
137  * capacity) will cause new tasks to be queued in cases where all
138  * corePoolSize threads are busy. Thus, no more than corePoolSize
139  * threads will ever be created. (And the value of the maximumPoolSize
140  * therefore doesn't have any effect.) This may be appropriate when
141  * each task is completely independent of others, so tasks cannot
142  * affect each others execution; for example, in a web page server.
143  * While this style of queuing can be useful in smoothing out
144  * transient bursts of requests, it admits the possibility of
145  * unbounded work queue growth when commands continue to arrive on
146  * average faster than they can be processed. </li>
147  *
148  * <li><em>Bounded queues.</em> A bounded queue (for example, an
149  * {@link ArrayBlockingQueue}) helps prevent resource exhaustion when
150  * used with finite maximumPoolSizes, but can be more difficult to
151  * tune and control. Queue sizes and maximum pool sizes may be traded
152  * off for each other: Using large queues and small pools minimizes
153  * CPU usage, OS resources, and context-switching overhead, but can
154  * lead to artificially low throughput. If tasks frequently block (for
155  * example if they are I/O bound), a system may be able to schedule
156  * time for more threads than you otherwise allow. Use of small queues
157  * generally requires larger pool sizes, which keeps CPUs busier but
158  * may encounter unacceptable scheduling overhead, which also
159  * decreases throughput. </li>
160  *
161  * </ol>
162  *
163  * </dd>
164  *
165  * <dt>Rejected tasks</dt>
166  *
167  * <dd> New tasks submitted in method {@link
168  * ThreadPoolExecutor#execute} will be <em>rejected</em> when the
169  * Executor has been shut down, and also when the Executor uses finite
170  * bounds for both maximum threads and work queue capacity, and is
171  * saturated. In either case, the <tt>execute</tt> method invokes the
172  * {@link RejectedExecutionHandler#rejectedExecution} method of its
173  * {@link RejectedExecutionHandler}. Four predefined handler policies
174  * are provided:
175  *
176  * <ol>
177  *
178  * <li> In the
179  * default {@link ThreadPoolExecutor.AbortPolicy}, the handler throws a
180  * runtime {@link RejectedExecutionException} upon rejection. </li>
181  *
182  * <li> In {@link
183  * ThreadPoolExecutor.CallerRunsPolicy}, the thread that invokes
184  * <tt>execute</tt> itself runs the task. This provides a simple
185  * feedback control mechanism that will slow down the rate that new
186  * tasks are submitted. </li>
187  *
188  * <li> In {@link ThreadPoolExecutor.DiscardPolicy},
189  * a task that cannot be executed is simply dropped. </li>
190  *
191  * <li>In {@link
192  * ThreadPoolExecutor.DiscardOldestPolicy}, if the executor is not
193  * shut down, the task at the head of the work queue is dropped, and
194  * then execution is retried (which can fail again, causing this to be
195  * repeated.) </li>
196  *
197  * </ol>
198  *
199  * It is possible to define and use other kinds of {@link
200  * RejectedExecutionHandler} classes. Doing so requires some care
201  * especially when policies are designed to work only under particular
202  * capacity or queuing policies. </dd>
203  *
204  * <dt>Hook methods</dt>
205  *
206  * <dd>This class provides <tt>protected</tt> overridable {@link
207  * ThreadPoolExecutor#beforeExecute} and {@link
208  * ThreadPoolExecutor#afterExecute} methods that are called before and
209  * after execution of each task. These can be used to manipulate the
210  * execution environment; for example, reinitializing ThreadLocals,
211  * gathering statistics, or adding log entries. Additionally, method
212  * {@link ThreadPoolExecutor#terminated} can be overridden to perform
213  * any special processing that needs to be done once the Executor has
214  * fully terminated.
215  *
216  * <p>If hook or callback methods throw
217  * exceptions, internal worker threads may in turn fail and
218  * abruptly terminate.</dd>
219  *
220  * <dt>Queue maintenance</dt>
221  *
222  * <dd> Method {@link ThreadPoolExecutor#getQueue} allows access to
223  * the work queue for purposes of monitoring and debugging. Use of
224  * this method for any other purpose is strongly discouraged. Two
225  * supplied methods, {@link ThreadPoolExecutor#remove} and {@link
226  * ThreadPoolExecutor#purge} are available to assist in storage
227  * reclamation when large numbers of queued tasks become
228  * cancelled.</dd> </dl>
229  *
230  * <p> <b>Extension example</b>. Most extensions of this class
231  * override one or more of the protected hook methods. For example,
232  * here is a subclass that adds a simple pause/resume feature:
233  *
234  * <pre>
235  * class PausableThreadPoolExecutor extends ThreadPoolExecutor {
236  * private boolean isPaused;
237  * private ReentrantLock pauseLock = new ReentrantLock();
238  * private Condition unpaused = pauseLock.newCondition();
239  *
240  * public PausableThreadPoolExecutor(...) { super(...); }
241  *
242  * protected void beforeExecute(Thread t, Runnable r) {
243  * super.beforeExecute(t, r);
244  * pauseLock.lock();
245  * try {
246  * while (isPaused) unpaused.await();
247  * } catch(InterruptedException ie) {
248  * t.interrupt();
249  * } finally {
250  * pauseLock.unlock();
251  * }
252  * }
253  *
254  * public void pause() {
255  * pauseLock.lock();
256  * try {
257  * isPaused = true;
258  * } finally {
259  * pauseLock.unlock();
260  * }
261  * }
262  *
263  * public void resume() {
264  * pauseLock.lock();
265  * try {
266  * isPaused = false;
267  * unpaused.signalAll();
268  * } finally {
269  * pauseLock.unlock();
270  * }
271  * }
272  * }
273  * </pre>
274  * @since 1.5
275  * @author Doug Lea
276  */

277 public class ThreadPoolExecutor extends AbstractExecutorService JavaDoc {
278     /**
279      * Only used to force toArray() to produce a Runnable[].
280      */

281     private static final Runnable JavaDoc[] EMPTY_RUNNABLE_ARRAY = new Runnable JavaDoc[0];
282
283     /**
284      * Permission for checking shutdown
285      */

286     private static final RuntimePermission JavaDoc shutdownPerm =
287         new RuntimePermission JavaDoc("modifyThread");
288
289     /**
290      * Queue used for holding tasks and handing off to worker threads.
291      */

292     private final BlockingQueue JavaDoc<Runnable JavaDoc> workQueue;
293
294     /**
295      * Lock held on updates to poolSize, corePoolSize, maximumPoolSize, and
296      * workers set.
297      */

298     private final ReentrantLock mainLock = new ReentrantLock();
299
300     /**
301      * Wait condition to support awaitTermination
302      */

303     private final Condition termination = mainLock.newCondition();
304
305     /**
306      * Set containing all worker threads in pool.
307      */

308     private final HashSet<Worker> workers = new HashSet<Worker>();
309
310     /**
311      * Timeout in nanoseconds for idle threads waiting for work.
312      * Threads use this timeout only when there are more than
313      * corePoolSize present. Otherwise they wait forever for new work.
314      */

315     private volatile long keepAliveTime;
316
317     /**
318      * Core pool size, updated only while holding mainLock,
319      * but volatile to allow concurrent readability even
320      * during updates.
321      */

322     private volatile int corePoolSize;
323
324     /**
325      * Maximum pool size, updated only while holding mainLock
326      * but volatile to allow concurrent readability even
327      * during updates.
328      */

329     private volatile int maximumPoolSize;
330
331     /**
332      * Current pool size, updated only while holding mainLock
333      * but volatile to allow concurrent readability even
334      * during updates.
335      */

336     private volatile int poolSize;
337
338     /**
339      * Lifecycle state
340      */

341     volatile int runState;
342
343     // Special values for runState
344
/** Normal, not-shutdown mode */
345     static final int RUNNING = 0;
346     /** Controlled shutdown mode */
347     static final int SHUTDOWN = 1;
348     /** Immediate shutdown mode */
349     static final int STOP = 2;
350     /** Final state */
351     static final int TERMINATED = 3;
352
353     /**
354      * Handler called when saturated or shutdown in execute.
355      */

356     private volatile RejectedExecutionHandler JavaDoc handler;
357
358     /**
359      * Factory for new threads.
360      */

361     private volatile ThreadFactory JavaDoc threadFactory;
362
363     /**
364      * Tracks largest attained pool size.
365      */

366     private int largestPoolSize;
367
368     /**
369      * Counter for completed tasks. Updated only on termination of
370      * worker threads.
371      */

372     private long completedTaskCount;
373     
374     /**
375      * The default rejected execution handler
376      */

377     private static final RejectedExecutionHandler JavaDoc defaultHandler =
378         new AbortPolicy();
379
380     /**
381      * Invoke the rejected execution handler for the given command.
382      */

383     void reject(Runnable JavaDoc command) {
384         handler.rejectedExecution(command, this);
385     }
386
387     /**
388      * Create and return a new thread running firstTask as its first
389      * task. Call only while holding mainLock
390      * @param firstTask the task the new thread should run first (or
391      * null if none)
392      * @return the new thread, or null if threadFactory fails to create thread
393      */

394     private Thread JavaDoc addThread(Runnable JavaDoc firstTask) {
395         Worker w = new Worker(firstTask);
396         Thread JavaDoc t = threadFactory.newThread(w);
397         if (t != null) {
398             w.thread = t;
399             workers.add(w);
400             int nt = ++poolSize;
401             if (nt > largestPoolSize)
402                 largestPoolSize = nt;
403         }
404         return t;
405     }
406
407     /**
408      * Create and start a new thread running firstTask as its first
409      * task, only if fewer than corePoolSize threads are running.
410      * @param firstTask the task the new thread should run first (or
411      * null if none)
412      * @return true if successful.
413      */

414     private boolean addIfUnderCorePoolSize(Runnable JavaDoc firstTask) {
415         Thread JavaDoc t = null;
416         final ReentrantLock mainLock = this.mainLock;
417         mainLock.lock();
418         try {
419             if (poolSize < corePoolSize)
420                 t = addThread(firstTask);
421         } finally {
422             mainLock.unlock();
423         }
424         if (t == null)
425             return false;
426         t.start();
427         return true;
428     }
429
430     /**
431      * Create and start a new thread only if fewer than maximumPoolSize
432      * threads are running. The new thread runs as its first task the
433      * next task in queue, or if there is none, the given task.
434      * @param firstTask the task the new thread should run first (or
435      * null if none)
436      * @return null on failure, else the first task to be run by new thread.
437      */

438     private Runnable JavaDoc addIfUnderMaximumPoolSize(Runnable JavaDoc firstTask) {
439         Thread JavaDoc t = null;
440         Runnable JavaDoc next = null;
441         final ReentrantLock mainLock = this.mainLock;
442         mainLock.lock();
443         try {
444             if (poolSize < maximumPoolSize) {
445                 next = workQueue.poll();
446                 if (next == null)
447                     next = firstTask;
448                 t = addThread(next);
449             }
450         } finally {
451             mainLock.unlock();
452         }
453         if (t == null)
454             return null;
455         t.start();
456         return next;
457     }
458
459
460     /**
461      * Get the next task for a worker thread to run.
462      * @return the task
463      * @throws InterruptedException if interrupted while waiting for task
464      */

465     Runnable JavaDoc getTask() throws InterruptedException JavaDoc {
466         for (;;) {
467             switch(runState) {
468             case RUNNING: {
469                 if (poolSize <= corePoolSize) // untimed wait if core
470
return workQueue.take();
471                 
472                 long timeout = keepAliveTime;
473                 if (timeout <= 0) // die immediately for 0 timeout
474
return null;
475                 Runnable JavaDoc r = workQueue.poll(timeout, TimeUnit.NANOSECONDS);
476                 if (r != null)
477                     return r;
478                 if (poolSize > corePoolSize) // timed out
479
return null;
480                 // else, after timeout, pool shrank so shouldn't die, so retry
481
break;
482             }
483
484             case SHUTDOWN: {
485                 // Help drain queue
486
Runnable JavaDoc r = workQueue.poll();
487                 if (r != null)
488                     return r;
489                     
490                 // Check if can terminate
491
if (workQueue.isEmpty()) {
492                     interruptIdleWorkers();
493                     return null;
494                 }
495
496                 // There could still be delayed tasks in queue.
497
// Wait for one, re-checking state upon interruption
498
try {
499                     return workQueue.take();
500                 } catch(InterruptedException JavaDoc ignore) {}
501                 break;
502             }
503
504             case STOP:
505                 return null;
506             default:
507                 assert false;
508             }
509         }
510     }
511
512     /**
513      * Wake up all threads that might be waiting for tasks.
514      */

515     void interruptIdleWorkers() {
516         final ReentrantLock mainLock = this.mainLock;
517         mainLock.lock();
518         try {
519             for (Worker w : workers)
520                 w.interruptIfIdle();
521         } finally {
522             mainLock.unlock();
523         }
524     }
525
526     /**
527      * Perform bookkeeping for a terminated worker thread.
528      * @param w the worker
529      */

530     void workerDone(Worker w) {
531         final ReentrantLock mainLock = this.mainLock;
532         mainLock.lock();
533         try {
534             completedTaskCount += w.completedTasks;
535             workers.remove(w);
536             if (--poolSize > 0)
537                 return;
538
539             // Else, this is the last thread. Deal with potential shutdown.
540

541             int state = runState;
542             assert state != TERMINATED;
543
544             if (state != STOP) {
545                 // If there are queued tasks but no threads, create
546
// replacement thread. We must create it initially
547
// idle to avoid orphaned tasks in case addThread
548
// fails. This also handles case of delayed tasks
549
// that will sometime later become runnable.
550
if (!workQueue.isEmpty()) {
551                     Thread JavaDoc t = addThread(null);
552                     if (t != null)
553                         t.start();
554                     return;
555                 }
556
557                 // Otherwise, we can exit without replacement
558
if (state == RUNNING)
559                     return;
560             }
561
562             // Either state is STOP, or state is SHUTDOWN and there is
563
// no work to do. So we can terminate.
564
termination.signalAll();
565             runState = TERMINATED;
566             // fall through to call terminate() outside of lock.
567
} finally {
568             mainLock.unlock();
569         }
570
571         assert runState == TERMINATED;
572         terminated();
573     }
574
575     /**
576      * Worker threads
577      */

578     private class Worker implements Runnable JavaDoc {
579
580         /**
581          * The runLock is acquired and released surrounding each task
582          * execution. It mainly protects against interrupts that are
583          * intended to cancel the worker thread from instead
584          * interrupting the task being run.
585          */

586         private final ReentrantLock runLock = new ReentrantLock();
587
588         /**
589          * Initial task to run before entering run loop
590          */

591         private Runnable JavaDoc firstTask;
592
593         /**
594          * Per thread completed task counter; accumulated
595          * into completedTaskCount upon termination.
596          */

597         volatile long completedTasks;
598
599         /**
600          * Thread this worker is running in. Acts as a final field,
601          * but cannot be set until thread is created.
602          */

603         Thread JavaDoc thread;
604
605         Worker(Runnable JavaDoc firstTask) {
606             this.firstTask = firstTask;
607         }
608
609         boolean isActive() {
610             return runLock.isLocked();
611         }
612
613         /**
614          * Interrupt thread if not running a task
615          */

616         void interruptIfIdle() {
617             final ReentrantLock runLock = this.runLock;
618             if (runLock.tryLock()) {
619                 try {
620                     thread.interrupt();
621                 } finally {
622                     runLock.unlock();
623                 }
624             }
625         }
626
627         /**
628          * Cause thread to die even if running a task.
629          */

630         void interruptNow() {
631             thread.interrupt();
632         }
633
634         /**
635          * Run a single task between before/after methods.
636          */

637         private void runTask(Runnable JavaDoc task) {
638             final ReentrantLock runLock = this.runLock;
639             runLock.lock();
640             try {
641                 // Abort now if immediate cancel. Otherwise, we have
642
// committed to run this task.
643
if (runState == STOP)
644                     return;
645
646                 Thread.interrupted(); // clear interrupt status on entry
647
boolean ran = false;
648                 beforeExecute(thread, task);
649                 try {
650                     task.run();
651                     ran = true;
652                     afterExecute(task, null);
653                     ++completedTasks;
654                 } catch(RuntimeException JavaDoc ex) {
655                     if (!ran)
656                         afterExecute(task, ex);
657                     // Else the exception occurred within
658
// afterExecute itself in which case we don't
659
// want to call it again.
660
throw ex;
661                 }
662             } finally {
663                 runLock.unlock();
664             }
665         }
666
667         /**
668          * Main run loop
669          */

670         public void run() {
671             try {
672                 Runnable JavaDoc task = firstTask;
673                 firstTask = null;
674                 while (task != null || (task = getTask()) != null) {
675                     runTask(task);
676                     task = null; // unnecessary but can help GC
677
}
678             } catch(InterruptedException JavaDoc ie) {
679                 // fall through
680
} finally {
681                 workerDone(this);
682             }
683         }
684     }
685
686     // Public methods
687

688     /**
689      * Creates a new <tt>ThreadPoolExecutor</tt> with the given
690      * initial parameters and default thread factory and handler. It
691      * may be more convenient to use one of the {@link Executors}
692      * factory methods instead of this general purpose constructor.
693      *
694      * @param corePoolSize the number of threads to keep in the
695      * pool, even if they are idle.
696      * @param maximumPoolSize the maximum number of threads to allow in the
697      * pool.
698      * @param keepAliveTime when the number of threads is greater than
699      * the core, this is the maximum time that excess idle threads
700      * will wait for new tasks before terminating.
701      * @param unit the time unit for the keepAliveTime
702      * argument.
703      * @param workQueue the queue to use for holding tasks before they
704      * are executed. This queue will hold only the <tt>Runnable</tt>
705      * tasks submitted by the <tt>execute</tt> method.
706      * @throws IllegalArgumentException if corePoolSize, or
707      * keepAliveTime less than zero, or if maximumPoolSize less than or
708      * equal to zero, or if corePoolSize greater than maximumPoolSize.
709      * @throws NullPointerException if <tt>workQueue</tt> is null
710      */

711     public ThreadPoolExecutor(int corePoolSize,
712                               int maximumPoolSize,
713                               long keepAliveTime,
714                               TimeUnit JavaDoc unit,
715                               BlockingQueue JavaDoc<Runnable JavaDoc> workQueue) {
716         this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
717              Executors.defaultThreadFactory(), defaultHandler);
718     }
719
720     /**
721      * Creates a new <tt>ThreadPoolExecutor</tt> with the given initial
722      * parameters.
723      *
724      * @param corePoolSize the number of threads to keep in the
725      * pool, even if they are idle.
726      * @param maximumPoolSize the maximum number of threads to allow in the
727      * pool.
728      * @param keepAliveTime when the number of threads is greater than
729      * the core, this is the maximum time that excess idle threads
730      * will wait for new tasks before terminating.
731      * @param unit the time unit for the keepAliveTime
732      * argument.
733      * @param workQueue the queue to use for holding tasks before they
734      * are executed. This queue will hold only the <tt>Runnable</tt>
735      * tasks submitted by the <tt>execute</tt> method.
736      * @param threadFactory the factory to use when the executor
737      * creates a new thread.
738      * @throws IllegalArgumentException if corePoolSize, or
739      * keepAliveTime less than zero, or if maximumPoolSize less than or
740      * equal to zero, or if corePoolSize greater than maximumPoolSize.
741      * @throws NullPointerException if <tt>workQueue</tt>
742      * or <tt>threadFactory</tt> are null.
743      */

744     public ThreadPoolExecutor(int corePoolSize,
745                               int maximumPoolSize,
746                               long keepAliveTime,
747                               TimeUnit JavaDoc unit,
748                               BlockingQueue JavaDoc<Runnable JavaDoc> workQueue,
749                               ThreadFactory JavaDoc threadFactory) {
750         this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
751              threadFactory, defaultHandler);
752     }
753
754     /**
755      * Creates a new <tt>ThreadPoolExecutor</tt> with the given initial
756      * parameters.
757      *
758      * @param corePoolSize the number of threads to keep in the
759      * pool, even if they are idle.
760      * @param maximumPoolSize the maximum number of threads to allow in the
761      * pool.
762      * @param keepAliveTime when the number of threads is greater than
763      * the core, this is the maximum time that excess idle threads
764      * will wait for new tasks before terminating.
765      * @param unit the time unit for the keepAliveTime
766      * argument.
767      * @param workQueue the queue to use for holding tasks before they
768      * are executed. This queue will hold only the <tt>Runnable</tt>
769      * tasks submitted by the <tt>execute</tt> method.
770      * @param handler the handler to use when execution is blocked
771      * because the thread bounds and queue capacities are reached.
772      * @throws IllegalArgumentException if corePoolSize, or
773      * keepAliveTime less than zero, or if maximumPoolSize less than or
774      * equal to zero, or if corePoolSize greater than maximumPoolSize.
775      * @throws NullPointerException if <tt>workQueue</tt>
776      * or <tt>handler</tt> are null.
777      */

778     public ThreadPoolExecutor(int corePoolSize,
779                               int maximumPoolSize,
780                               long keepAliveTime,
781                               TimeUnit JavaDoc unit,
782                               BlockingQueue JavaDoc<Runnable JavaDoc> workQueue,
783                               RejectedExecutionHandler JavaDoc handler) {
784         this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
785              Executors.defaultThreadFactory(), handler);
786     }
787
788     /**
789      * Creates a new <tt>ThreadPoolExecutor</tt> with the given initial
790      * parameters.
791      *
792      * @param corePoolSize the number of threads to keep in the
793      * pool, even if they are idle.
794      * @param maximumPoolSize the maximum number of threads to allow in the
795      * pool.
796      * @param keepAliveTime when the number of threads is greater than
797      * the core, this is the maximum time that excess idle threads
798      * will wait for new tasks before terminating.
799      * @param unit the time unit for the keepAliveTime
800      * argument.
801      * @param workQueue the queue to use for holding tasks before they
802      * are executed. This queue will hold only the <tt>Runnable</tt>
803      * tasks submitted by the <tt>execute</tt> method.
804      * @param threadFactory the factory to use when the executor
805      * creates a new thread.
806      * @param handler the handler to use when execution is blocked
807      * because the thread bounds and queue capacities are reached.
808      * @throws IllegalArgumentException if corePoolSize, or
809      * keepAliveTime less than zero, or if maximumPoolSize less than or
810      * equal to zero, or if corePoolSize greater than maximumPoolSize.
811      * @throws NullPointerException if <tt>workQueue</tt>
812      * or <tt>threadFactory</tt> or <tt>handler</tt> are null.
813      */

814     public ThreadPoolExecutor(int corePoolSize,
815                               int maximumPoolSize,
816                               long keepAliveTime,
817                               TimeUnit JavaDoc unit,
818                               BlockingQueue JavaDoc<Runnable JavaDoc> workQueue,
819                               ThreadFactory JavaDoc threadFactory,
820                               RejectedExecutionHandler JavaDoc handler) {
821         if (corePoolSize < 0 ||
822             maximumPoolSize <= 0 ||
823             maximumPoolSize < corePoolSize ||
824             keepAliveTime < 0)
825             throw new IllegalArgumentException JavaDoc();
826         if (workQueue == null || threadFactory == null || handler == null)
827             throw new NullPointerException JavaDoc();
828         this.corePoolSize = corePoolSize;
829         this.maximumPoolSize = maximumPoolSize;
830         this.workQueue = workQueue;
831         this.keepAliveTime = unit.toNanos(keepAliveTime);
832         this.threadFactory = threadFactory;
833         this.handler = handler;
834     }
835
836
837     /**
838      * Executes the given task sometime in the future. The task
839      * may execute in a new thread or in an existing pooled thread.
840      *
841      * If the task cannot be submitted for execution, either because this
842      * executor has been shutdown or because its capacity has been reached,
843      * the task is handled by the current <tt>RejectedExecutionHandler</tt>.
844      *
845      * @param command the task to execute
846      * @throws RejectedExecutionException at discretion of
847      * <tt>RejectedExecutionHandler</tt>, if task cannot be accepted
848      * for execution
849      * @throws NullPointerException if command is null
850      */

851     public void execute(Runnable JavaDoc command) {
852         if (command == null)
853             throw new NullPointerException JavaDoc();
854         for (;;) {
855             if (runState != RUNNING) {
856                 reject(command);
857                 return;
858             }
859             if (poolSize < corePoolSize && addIfUnderCorePoolSize(command))
860                 return;
861             if (workQueue.offer(command))
862                 return;
863             Runnable JavaDoc r = addIfUnderMaximumPoolSize(command);
864             if (r == command)
865                 return;
866             if (r == null) {
867                 reject(command);
868                 return;
869             }
870             // else retry
871
}
872     }
873
874     /**
875      * Initiates an orderly shutdown in which previously submitted
876      * tasks are executed, but no new tasks will be
877      * accepted. Invocation has no additional effect if already shut
878      * down.
879      * @throws SecurityException if a security manager exists and
880      * shutting down this ExecutorService may manipulate threads that
881      * the caller is not permitted to modify because it does not hold
882      * {@link java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
883      * or the security manager's <tt>checkAccess</tt> method denies access.
884      */

885     public void shutdown() {
886         // Fail if caller doesn't have modifyThread permission. We
887
// explicitly check permissions directly because we can't trust
888
// implementations of SecurityManager to correctly override
889
// the "check access" methods such that our documented
890
// security policy is implemented.
891
SecurityManager JavaDoc security = System.getSecurityManager();
892     if (security != null)
893             java.security.AccessController.checkPermission(shutdownPerm);
894
895         boolean fullyTerminated = false;
896         final ReentrantLock mainLock = this.mainLock;
897         mainLock.lock();
898         try {
899             if (workers.size() > 0) {
900                 // Check if caller can modify worker threads. This
901
// might not be true even if passed above check, if
902
// the SecurityManager treats some threads specially.
903
if (security != null) {
904                     for (Worker w: workers)
905                         security.checkAccess(w.thread);
906                 }
907
908                 int state = runState;
909                 if (state == RUNNING) // don't override shutdownNow
910
runState = SHUTDOWN;
911
912                 try {
913                     for (Worker w: workers)
914                         w.interruptIfIdle();
915                 } catch(SecurityException JavaDoc se) {
916                     // If SecurityManager allows above checks, but
917
// then unexpectedly throws exception when
918
// interrupting threads (which it ought not do),
919
// back out as cleanly as we can. Some threads may
920
// have been killed but we remain in non-shutdown
921
// state.
922
runState = state;
923                     throw se;
924                 }
925             }
926             else { // If no workers, trigger full termination now
927
fullyTerminated = true;
928                 runState = TERMINATED;
929                 termination.signalAll();
930             }
931         } finally {
932             mainLock.unlock();
933         }
934         if (fullyTerminated)
935             terminated();
936     }
937
938
939     /**
940      * Attempts to stop all actively executing tasks, halts the
941      * processing of waiting tasks, and returns a list of the tasks that were
942      * awaiting execution.
943      *
944      * <p>This implementation cancels tasks via {@link
945      * Thread#interrupt}, so if any tasks mask or fail to respond to
946      * interrupts, they may never terminate.
947      *
948      * @return list of tasks that never commenced execution
949      * @throws SecurityException if a security manager exists and
950      * shutting down this ExecutorService may manipulate threads that
951      * the caller is not permitted to modify because it does not hold
952      * {@link java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
953      * or the security manager's <tt>checkAccess</tt> method denies access.
954      */

955     public List<Runnable JavaDoc> shutdownNow() {
956         // Almost the same code as shutdown()
957
SecurityManager JavaDoc security = System.getSecurityManager();
958     if (security != null)
959             java.security.AccessController.checkPermission(shutdownPerm);
960
961         boolean fullyTerminated = false;
962         final ReentrantLock mainLock = this.mainLock;
963         mainLock.lock();
964         try {
965             if (workers.size() > 0) {
966                 if (security != null) {
967                     for (Worker w: workers)
968                         security.checkAccess(w.thread);
969                 }
970
971                 int state = runState;
972                 if (state != TERMINATED)
973                     runState = STOP;
974                 try {
975                     for (Worker w : workers)
976                         w.interruptNow();
977                 } catch(SecurityException JavaDoc se) {
978                     runState = state; // back out;
979
throw se;
980                 }
981             }
982             else { // If no workers, trigger full termination now
983
fullyTerminated = true;
984                 runState = TERMINATED;
985                 termination.signalAll();
986             }
987         } finally {
988             mainLock.unlock();
989         }
990         if (fullyTerminated)
991             terminated();
992         return Arrays.asList(workQueue.toArray(EMPTY_RUNNABLE_ARRAY));
993     }
994
995     public boolean isShutdown() {
996         return runState != RUNNING;
997     }
998
999     /**
1000     * Returns true if this executor is in the process of terminating
1001     * after <tt>shutdown</tt> or <tt>shutdownNow</tt> but has not
1002     * completely terminated. This method may be useful for
1003     * debugging. A return of <tt>true</tt> reported a sufficient
1004     * period after shutdown may indicate that submitted tasks have
1005     * ignored or suppressed interruption, causing this executor not
1006     * to properly terminate.
1007     * @return true if terminating but not yet terminated.
1008     */

1009    public boolean isTerminating() {
1010        return runState == STOP;
1011    }
1012
1013    public boolean isTerminated() {
1014        return runState == TERMINATED;
1015    }
1016
1017    public boolean awaitTermination(long timeout, TimeUnit JavaDoc unit)
1018        throws InterruptedException JavaDoc {
1019        long nanos = unit.toNanos(timeout);
1020        final ReentrantLock mainLock = this.mainLock;
1021        mainLock.lock();
1022        try {
1023            for (;;) {
1024                if (runState == TERMINATED)
1025                    return true;
1026                if (nanos <= 0)
1027                    return false;
1028                nanos = termination.awaitNanos(nanos);
1029            }
1030        } finally {
1031            mainLock.unlock();
1032        }
1033    }
1034
1035    /**
1036     * Invokes <tt>shutdown</tt> when this executor is no longer
1037     * referenced.
1038     */

1039    protected void finalize() {
1040        shutdown();
1041    }
1042
1043    /**
1044     * Sets the thread factory used to create new threads.
1045     *
1046     * @param threadFactory the new thread factory
1047     * @throws NullPointerException if threadFactory is null
1048     * @see #getThreadFactory
1049     */

1050    public void setThreadFactory(ThreadFactory JavaDoc threadFactory) {
1051        if (threadFactory == null)
1052            throw new NullPointerException JavaDoc();
1053        this.threadFactory = threadFactory;
1054    }
1055
1056    /**
1057     * Returns the thread factory used to create new threads.
1058     *
1059     * @return the current thread factory
1060     * @see #setThreadFactory
1061     */

1062    public ThreadFactory JavaDoc getThreadFactory() {
1063        return threadFactory;
1064    }
1065
1066    /**
1067     * Sets a new handler for unexecutable tasks.
1068     *
1069     * @param handler the new handler
1070     * @throws NullPointerException if handler is null
1071     * @see #getRejectedExecutionHandler
1072     */

1073    public void setRejectedExecutionHandler(RejectedExecutionHandler JavaDoc handler) {
1074        if (handler == null)
1075            throw new NullPointerException JavaDoc();
1076        this.handler = handler;
1077    }
1078
1079    /**
1080     * Returns the current handler for unexecutable tasks.
1081     *
1082     * @return the current handler
1083     * @see #setRejectedExecutionHandler
1084     */

1085    public RejectedExecutionHandler JavaDoc getRejectedExecutionHandler() {
1086        return handler;
1087    }
1088
1089    /**
1090     * Returns the task queue used by this executor. Access to the
1091     * task queue is intended primarily for debugging and monitoring.
1092     * This queue may be in active use. Retrieving the task queue
1093     * does not prevent queued tasks from executing.
1094     *
1095     * @return the task queue
1096     */

1097    public BlockingQueue JavaDoc<Runnable JavaDoc> getQueue() {
1098        return workQueue;
1099    }
1100
1101    /**
1102     * Removes this task from the executor's internal queue if it is
1103     * present, thus causing it not to be run if it has not already
1104     * started.
1105     *
1106     * <p> This method may be useful as one part of a cancellation
1107     * scheme. It may fail to remove tasks that have been converted
1108     * into other forms before being placed on the internal queue. For
1109     * example, a task entered using <tt>submit</tt> might be
1110     * converted into a form that maintains <tt>Future</tt> status.
1111     * However, in such cases, method {@link ThreadPoolExecutor#purge}
1112     * may be used to remove those Futures that have been cancelled.
1113     *
1114     *
1115     * @param task the task to remove
1116     * @return true if the task was removed
1117     */

1118    public boolean remove(Runnable JavaDoc task) {
1119        return getQueue().remove(task);
1120    }
1121
1122
1123    /**
1124     * Tries to remove from the work queue all {@link Future}
1125     * tasks that have been cancelled. This method can be useful as a
1126     * storage reclamation operation, that has no other impact on
1127     * functionality. Cancelled tasks are never executed, but may
1128     * accumulate in work queues until worker threads can actively
1129     * remove them. Invoking this method instead tries to remove them now.
1130     * However, this method may fail to remove tasks in
1131     * the presence of interference by other threads.
1132     */

1133    public void purge() {
1134        // Fail if we encounter interference during traversal
1135
try {
1136            Iterator<Runnable JavaDoc> it = getQueue().iterator();
1137            while (it.hasNext()) {
1138                Runnable JavaDoc r = it.next();
1139                if (r instanceof Future JavaDoc<?>) {
1140                    Future JavaDoc<?> c = (Future JavaDoc<?>)r;
1141                    if (c.isCancelled())
1142                        it.remove();
1143                }
1144            }
1145        }
1146        catch(ConcurrentModificationException ex) {
1147            return;
1148        }
1149    }
1150
1151    /**
1152     * Sets the core number of threads. This overrides any value set
1153     * in the constructor. If the new value is smaller than the
1154     * current value, excess existing threads will be terminated when
1155     * they next become idle. If larger, new threads will, if needed,
1156     * be started to execute any queued tasks.
1157     *
1158     * @param corePoolSize the new core size
1159     * @throws IllegalArgumentException if <tt>corePoolSize</tt>
1160     * less than zero
1161     * @see #getCorePoolSize
1162     */

1163    public void setCorePoolSize(int corePoolSize) {
1164        if (corePoolSize < 0)
1165            throw new IllegalArgumentException JavaDoc();
1166        final ReentrantLock mainLock = this.mainLock;
1167        mainLock.lock();
1168        try {
1169            int extra = this.corePoolSize - corePoolSize;
1170            this.corePoolSize = corePoolSize;
1171            if (extra < 0) {
1172                int n = workQueue.size();
1173                // We have to create initially-idle threads here
1174
// because we otherwise have no recourse about
1175
// what to do with a dequeued task if addThread fails.
1176
while (extra++ < 0 && n-- > 0 && poolSize < corePoolSize ) {
1177                    Thread JavaDoc t = addThread(null);
1178                    if (t != null)
1179                        t.start();
1180                    else
1181                        break;
1182                }
1183            }
1184            else if (extra > 0 && poolSize > corePoolSize) {
1185                Iterator<Worker> it = workers.iterator();
1186                while (it.hasNext() &&
1187                       extra-- > 0 &&
1188                       poolSize > corePoolSize &&
1189                       workQueue.remainingCapacity() == 0)
1190                    it.next().interruptIfIdle();
1191            }
1192        } finally {
1193            mainLock.unlock();
1194        }
1195    }
1196
1197    /**
1198     * Returns the core number of threads.
1199     *
1200     * @return the core number of threads
1201     * @see #setCorePoolSize
1202     */

1203    public int getCorePoolSize() {
1204        return corePoolSize;
1205    }
1206
1207    /**
1208     * Starts a core thread, causing it to idly wait for work. This
1209     * overrides the default policy of starting core threads only when
1210     * new tasks are executed. This method will return <tt>false</tt>
1211     * if all core threads have already been started.
1212     * @return true if a thread was started
1213     */

1214    public boolean prestartCoreThread() {
1215        return addIfUnderCorePoolSize(null);
1216    }
1217
1218    /**
1219     * Starts all core threads, causing them to idly wait for work. This
1220     * overrides the default policy of starting core threads only when
1221     * new tasks are executed.
1222     * @return the number of threads started.
1223     */

1224    public int prestartAllCoreThreads() {
1225        int n = 0;
1226        while (addIfUnderCorePoolSize(null))
1227            ++n;
1228        return n;
1229    }
1230
1231    /**
1232     * Sets the maximum allowed number of threads. This overrides any
1233     * value set in the constructor. If the new value is smaller than
1234     * the current value, excess existing threads will be
1235     * terminated when they next become idle.
1236     *
1237     * @param maximumPoolSize the new maximum
1238     * @throws IllegalArgumentException if maximumPoolSize less than zero or
1239     * the {@link #getCorePoolSize core pool size}
1240     * @see #getMaximumPoolSize
1241     */

1242    public void setMaximumPoolSize(int maximumPoolSize) {
1243        if (maximumPoolSize <= 0 || maximumPoolSize < corePoolSize)
1244            throw new IllegalArgumentException JavaDoc();
1245        final ReentrantLock mainLock = this.mainLock;
1246        mainLock.lock();
1247        try {
1248            int extra = this.maximumPoolSize - maximumPoolSize;
1249            this.maximumPoolSize = maximumPoolSize;
1250            if (extra > 0 && poolSize > maximumPoolSize) {
1251                Iterator<Worker> it = workers.iterator();
1252                while (it.hasNext() &&
1253                       extra > 0 &&
1254                       poolSize > maximumPoolSize) {
1255                    it.next().interruptIfIdle();
1256                    --extra;
1257                }
1258            }
1259        } finally {
1260            mainLock.unlock();
1261        }
1262    }
1263
1264    /**
1265     * Returns the maximum allowed number of threads.
1266     *
1267     * @return the maximum allowed number of threads
1268     * @see #setMaximumPoolSize
1269     */

1270    public int getMaximumPoolSize() {
1271        return maximumPoolSize;
1272    }
1273
1274    /**
1275     * Sets the time limit for which threads may remain idle before
1276     * being terminated. If there are more than the core number of
1277     * threads currently in the pool, after waiting this amount of
1278     * time without processing a task, excess threads will be
1279     * terminated. This overrides any value set in the constructor.
1280     * @param time the time to wait. A time value of zero will cause
1281     * excess threads to terminate immediately after executing tasks.
1282     * @param unit the time unit of the time argument
1283     * @throws IllegalArgumentException if time less than zero
1284     * @see #getKeepAliveTime
1285     */

1286    public void setKeepAliveTime(long time, TimeUnit JavaDoc unit) {
1287        if (time < 0)
1288            throw new IllegalArgumentException JavaDoc();
1289        this.keepAliveTime = unit.toNanos(time);
1290    }
1291
1292    /**
1293     * Returns the thread keep-alive time, which is the amount of time
1294     * which threads in excess of the core pool size may remain
1295     * idle before being terminated.
1296     *
1297     * @param unit the desired time unit of the result
1298     * @return the time limit
1299     * @see #setKeepAliveTime
1300     */

1301    public long getKeepAliveTime(TimeUnit JavaDoc unit) {
1302        return unit.convert(keepAliveTime, TimeUnit.NANOSECONDS);
1303    }
1304
1305    /* Statistics */
1306
1307    /**
1308     * Returns the current number of threads in the pool.
1309     *
1310     * @return the number of threads
1311     */

1312    public int getPoolSize() {
1313        return poolSize;
1314    }
1315
1316    /**
1317     * Returns the approximate number of threads that are actively
1318     * executing tasks.
1319     *
1320     * @return the number of threads
1321     */

1322    public int getActiveCount() {
1323        final ReentrantLock mainLock = this.mainLock;
1324        mainLock.lock();
1325        try {
1326            int n = 0;
1327            for (Worker w : workers) {
1328                if (w.isActive())
1329                    ++n;
1330            }
1331            return n;
1332        } finally {
1333            mainLock.unlock();
1334        }
1335    }
1336
1337    /**
1338     * Returns the largest number of threads that have ever
1339     * simultaneously been in the pool.
1340     *
1341     * @return the number of threads
1342     */

1343    public int getLargestPoolSize() {
1344        final ReentrantLock mainLock = this.mainLock;
1345        mainLock.lock();
1346        try {
1347            return largestPoolSize;
1348        } finally {
1349            mainLock.unlock();
1350        }
1351    }
1352
1353    /**
1354     * Returns the approximate total number of tasks that have been
1355     * scheduled for execution. Because the states of tasks and
1356     * threads may change dynamically during computation, the returned
1357     * value is only an approximation, but one that does not ever
1358     * decrease across successive calls.
1359     *
1360     * @return the number of tasks
1361     */

1362    public long getTaskCount() {
1363        final ReentrantLock mainLock = this.mainLock;
1364        mainLock.lock();
1365        try {
1366            long n = completedTaskCount;
1367            for (Worker w : workers) {
1368                n += w.completedTasks;
1369                if (w.isActive())
1370                    ++n;
1371            }
1372            return n + workQueue.size();
1373        } finally {
1374            mainLock.unlock();
1375        }
1376    }
1377
1378    /**
1379     * Returns the approximate total number of tasks that have
1380     * completed execution. Because the states of tasks and threads
1381     * may change dynamically during computation, the returned value
1382     * is only an approximation, but one that does not ever decrease
1383     * across successive calls.
1384     *
1385     * @return the number of tasks
1386     */

1387    public long getCompletedTaskCount() {
1388        final ReentrantLock mainLock = this.mainLock;
1389        mainLock.lock();
1390        try {
1391            long n = completedTaskCount;
1392            for (Worker w : workers)
1393                n += w.completedTasks;
1394            return n;
1395        } finally {
1396            mainLock.unlock();
1397        }
1398    }
1399
1400    /**
1401     * Method invoked prior to executing the given Runnable in the
1402     * given thread. This method is invoked by thread <tt>t</tt> that
1403     * will execute task <tt>r</tt>, and may be used to re-initialize
1404     * ThreadLocals, or to perform logging. Note: To properly nest
1405     * multiple overridings, subclasses should generally invoke
1406     * <tt>super.beforeExecute</tt> at the end of this method.
1407     *
1408     * @param t the thread that will run task r.
1409     * @param r the task that will be executed.
1410     */

1411    protected void beforeExecute(Thread JavaDoc t, Runnable JavaDoc r) { }
1412
1413    /**
1414     * Method invoked upon completion of execution of the given
1415     * Runnable. This method is invoked by the thread that executed
1416     * the task. If non-null, the Throwable is the uncaught exception
1417     * that caused execution to terminate abruptly. Note: To properly
1418     * nest multiple overridings, subclasses should generally invoke
1419     * <tt>super.afterExecute</tt> at the beginning of this method.
1420     *
1421     * @param r the runnable that has completed.
1422     * @param t the exception that caused termination, or null if
1423     * execution completed normally.
1424     */

1425    protected void afterExecute(Runnable JavaDoc r, Throwable JavaDoc t) { }
1426
1427    /**
1428     * Method invoked when the Executor has terminated. Default
1429     * implementation does nothing. Note: To properly nest multiple
1430     * overridings, subclasses should generally invoke
1431     * <tt>super.terminated</tt> within this method.
1432     */

1433    protected void terminated() { }
1434
1435    /**
1436     * A handler for rejected tasks that runs the rejected task
1437     * directly in the calling thread of the <tt>execute</tt> method,
1438     * unless the executor has been shut down, in which case the task
1439     * is discarded.
1440     */

1441   public static class CallerRunsPolicy implements RejectedExecutionHandler JavaDoc {
1442        /**
1443         * Creates a <tt>CallerRunsPolicy</tt>.
1444         */

1445        public CallerRunsPolicy() { }
1446
1447        /**
1448         * Executes task r in the caller's thread, unless the executor
1449         * has been shut down, in which case the task is discarded.
1450         * @param r the runnable task requested to be executed
1451         * @param e the executor attempting to execute this task
1452         */

1453        public void rejectedExecution(Runnable JavaDoc r, ThreadPoolExecutor JavaDoc e) {
1454            if (!e.isShutdown()) {
1455                r.run();
1456            }
1457        }
1458    }
1459
1460    /**
1461     * A handler for rejected tasks that throws a
1462     * <tt>RejectedExecutionException</tt>.
1463     */

1464    public static class AbortPolicy implements RejectedExecutionHandler JavaDoc {
1465        /**
1466         * Creates an <tt>AbortPolicy</tt>.
1467         */

1468        public AbortPolicy() { }
1469
1470        /**
1471         * Always throws RejectedExecutionException.
1472         * @param r the runnable task requested to be executed
1473         * @param e the executor attempting to execute this task
1474         * @throws RejectedExecutionException always.
1475         */

1476        public void rejectedExecution(Runnable JavaDoc r, ThreadPoolExecutor JavaDoc e) {
1477            throw new RejectedExecutionException JavaDoc();
1478        }
1479    }
1480
1481    /**
1482     * A handler for rejected tasks that silently discards the
1483     * rejected task.
1484     */

1485    public static class DiscardPolicy implements RejectedExecutionHandler JavaDoc {
1486        /**
1487         * Creates a <tt>DiscardPolicy</tt>.
1488         */

1489        public DiscardPolicy() { }
1490
1491        /**
1492         * Does nothing, which has the effect of discarding task r.
1493         * @param r the runnable task requested to be executed
1494         * @param e the executor attempting to execute this task
1495         */

1496        public void rejectedExecution(Runnable JavaDoc r, ThreadPoolExecutor JavaDoc e) {
1497        }
1498    }
1499
1500    /**
1501     * A handler for rejected tasks that discards the oldest unhandled
1502     * request and then retries <tt>execute</tt>, unless the executor
1503     * is shut down, in which case the task is discarded.
1504     */

1505    public static class DiscardOldestPolicy implements RejectedExecutionHandler JavaDoc {
1506        /**
1507         * Creates a <tt>DiscardOldestPolicy</tt> for the given executor.
1508         */

1509        public DiscardOldestPolicy() { }
1510
1511        /**
1512         * Obtains and ignores the next task that the executor
1513         * would otherwise execute, if one is immediately available,
1514         * and then retries execution of task r, unless the executor
1515         * is shut down, in which case task r is instead discarded.
1516         * @param r the runnable task requested to be executed
1517         * @param e the executor attempting to execute this task
1518         */

1519        public void rejectedExecution(Runnable JavaDoc r, ThreadPoolExecutor JavaDoc e) {
1520            if (!e.isShutdown()) {
1521                e.getQueue().poll();
1522                e.execute(r);
1523            }
1524        }
1525    }
1526}
1527
Popular Tags