1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Written by Doug Lea with assistance from members of JCP JSR-166
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Expert Group and released to the public domain, as explained at
4a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * http://creativecommons.org/publicdomain/zero/1.0/
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util.concurrent;
88eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilsonimport java.util.concurrent.locks.*;
98eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilsonimport java.util.concurrent.atomic.*;
108eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilsonimport java.util.*;
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
12a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson// BEGIN android-note
13a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson// removed security manager docs
14a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson// END android-note
15a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * An {@link ExecutorService} that executes each submitted task using
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * one of possibly several pooled threads, normally configured
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * using {@link Executors} factory methods.
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p>Thread pools address two different problems: they usually
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * provide improved performance when executing large numbers of
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * asynchronous tasks, due to reduced per-task invocation overhead,
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and they provide a means of bounding and managing the resources,
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * including threads, consumed when executing a collection of tasks.
26bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Each {@code ThreadPoolExecutor} also maintains some basic
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * statistics, such as the number of completed tasks.
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p>To be useful across a wide range of contexts, this class
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * provides many adjustable parameters and extensibility
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * hooks. However, programmers are urged to use the more convenient
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link Executors} factory methods {@link
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Executors#newCachedThreadPool} (unbounded thread pool, with
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * automatic thread reclamation), {@link Executors#newFixedThreadPool}
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (fixed size thread pool) and {@link
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Executors#newSingleThreadExecutor} (single background thread), that
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * preconfigure settings for the most common usage
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * scenarios. Otherwise, use the following guide when manually
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * configuring and tuning this class:
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <dl>
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <dt>Core and maximum pool sizes</dt>
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
45bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <dd>A {@code ThreadPoolExecutor} will automatically adjust the
46bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * pool size (see {@link #getPoolSize})
47bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * according to the bounds set by
48bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * corePoolSize (see {@link #getCorePoolSize}) and
49bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * maximumPoolSize (see {@link #getMaximumPoolSize}).
50bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *
51bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * When a new task is submitted in method {@link #execute}, and fewer
52bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * than corePoolSize threads are running, a new thread is created to
53bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * handle the request, even if other worker threads are idle.  If
54bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * there are more than corePoolSize but less than maximumPoolSize
55bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * threads running, a new thread will be created only if the queue is
56bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * full.  By setting corePoolSize and maximumPoolSize the same, you
57bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * create a fixed-size thread pool. By setting maximumPoolSize to an
58bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * essentially unbounded value such as {@code Integer.MAX_VALUE}, you
59bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * allow the pool to accommodate an arbitrary number of concurrent
60bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * tasks. Most typically, core and maximum pool sizes are set only
61bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * upon construction, but they may also be changed dynamically using
62bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * {@link #setCorePoolSize} and {@link #setMaximumPoolSize}. </dd>
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
64bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <dt>On-demand construction</dt>
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <dd> By default, even core threads are initially created and
67bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * started only when new tasks arrive, but this can be overridden
68bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * dynamically using method {@link #prestartCoreThread} or {@link
69bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * #prestartAllCoreThreads}.  You probably want to prestart threads if
70bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * you construct the pool with a non-empty queue. </dd>
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <dt>Creating new threads</dt>
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
74bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <dd>New threads are created using a {@link ThreadFactory}.  If not
75bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * otherwise specified, a {@link Executors#defaultThreadFactory} is
76bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * used, that creates threads to all be in the same {@link
77bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * ThreadGroup} and with the same {@code NORM_PRIORITY} priority and
78bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * non-daemon status. By supplying a different ThreadFactory, you can
79bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * alter the thread's name, thread group, priority, daemon status,
80bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * etc. If a {@code ThreadFactory} fails to create a thread when asked
81bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * by returning null from {@code newThread}, the executor will
82ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes * continue, but might not be able to execute any tasks.</dd>
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <dt>Keep-alive times</dt>
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <dd>If the pool currently has more than corePoolSize threads,
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * excess threads will be terminated if they have been idle for more
88bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * than the keepAliveTime (see {@link #getKeepAliveTime}). This
89bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * provides a means of reducing resource consumption when the pool is
90bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * not being actively used. If the pool becomes more active later, new
91bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * threads will be constructed. This parameter can also be changed
92bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * dynamically using method {@link #setKeepAliveTime}. Using a value
93bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * of {@code Long.MAX_VALUE} {@link TimeUnit#NANOSECONDS} effectively
946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * disables idle threads from ever terminating prior to shut down. By
956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * default, the keep-alive policy applies only when there are more
966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * than corePoolSizeThreads. But method {@link
976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * #allowCoreThreadTimeOut(boolean)} can be used to apply this
986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * time-out policy to core threads as well, so long as the
996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * keepAliveTime value is non-zero. </dd>
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <dt>Queuing</dt>
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <dd>Any {@link BlockingQueue} may be used to transfer and hold
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * submitted tasks.  The use of this queue interacts with pool sizing:
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <ul>
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li> If fewer than corePoolSize threads are running, the Executor
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * always prefers adding a new thread
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * rather than queuing.</li>
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li> If corePoolSize or more threads are running, the Executor
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * always prefers queuing a request rather than adding a new
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * thread.</li>
115bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li> If a request cannot be queued, a new thread is created unless
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this would exceed maximumPoolSize, in which case, the task will be
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * rejected.</li>
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </ul>
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * There are three general strategies for queuing:
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <ol>
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li> <em> Direct handoffs.</em> A good default choice for a work
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * queue is a {@link SynchronousQueue} that hands off tasks to threads
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * without otherwise holding them. Here, an attempt to queue a task
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * will fail if no threads are immediately available to run it, so a
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * new thread will be constructed. This policy avoids lockups when
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * handling sets of requests that might have internal dependencies.
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Direct handoffs generally require unbounded maximumPoolSizes to
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * avoid rejection of new submitted tasks. This in turn admits the
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * possibility of unbounded thread growth when commands continue to
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * arrive on average faster than they can be processed.  </li>
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li><em> Unbounded queues.</em> Using an unbounded queue (for
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * example a {@link LinkedBlockingQueue} without a predefined
138bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * capacity) will cause new tasks to wait in the queue when all
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * corePoolSize threads are busy. Thus, no more than corePoolSize
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * threads will ever be created. (And the value of the maximumPoolSize
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * therefore doesn't have any effect.)  This may be appropriate when
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * each task is completely independent of others, so tasks cannot
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * affect each others execution; for example, in a web page server.
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * While this style of queuing can be useful in smoothing out
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * transient bursts of requests, it admits the possibility of
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * unbounded work queue growth when commands continue to arrive on
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * average faster than they can be processed.  </li>
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li><em>Bounded queues.</em> A bounded queue (for example, an
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link ArrayBlockingQueue}) helps prevent resource exhaustion when
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * used with finite maximumPoolSizes, but can be more difficult to
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * tune and control.  Queue sizes and maximum pool sizes may be traded
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * off for each other: Using large queues and small pools minimizes
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * CPU usage, OS resources, and context-switching overhead, but can
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * lead to artificially low throughput.  If tasks frequently block (for
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * example if they are I/O bound), a system may be able to schedule
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * time for more threads than you otherwise allow. Use of small queues
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * generally requires larger pool sizes, which keeps CPUs busier but
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * may encounter unacceptable scheduling overhead, which also
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decreases throughput.  </li>
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </ol>
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </dd>
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <dt>Rejected tasks</dt>
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
168bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <dd> New tasks submitted in method {@link #execute} will be
169bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <em>rejected</em> when the Executor has been shut down, and also
170bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * when the Executor uses finite bounds for both maximum threads and
171bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * work queue capacity, and is saturated.  In either case, the {@code
172bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * execute} method invokes the {@link
173bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * RejectedExecutionHandler#rejectedExecution} method of its {@link
174bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * RejectedExecutionHandler}.  Four predefined handler policies are
175bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * provided:
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <ol>
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
179bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <li> In the default {@link ThreadPoolExecutor.AbortPolicy}, the
180bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * handler throws a runtime {@link RejectedExecutionException} upon
181bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * rejection. </li>
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
183bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <li> In {@link ThreadPoolExecutor.CallerRunsPolicy}, the thread
184bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * that invokes {@code execute} itself runs the task. This provides a
185bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * simple feedback control mechanism that will slow down the rate that
186bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * new tasks are submitted. </li>
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
188bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <li> In {@link ThreadPoolExecutor.DiscardPolicy}, a task that
189bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * cannot be executed is simply dropped.  </li>
190bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *
191bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <li>In {@link ThreadPoolExecutor.DiscardOldestPolicy}, if the
192bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * executor is not shut down, the task at the head of the work queue
193bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * is dropped, and then execution is retried (which can fail again,
194bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * causing this to be repeated.) </li>
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </ol>
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * It is possible to define and use other kinds of {@link
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * RejectedExecutionHandler} classes. Doing so requires some care
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * especially when policies are designed to work only under particular
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * capacity or queuing policies. </dd>
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <dt>Hook methods</dt>
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
205bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <dd>This class provides {@code protected} overridable {@link
206bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * #beforeExecute} and {@link #afterExecute} methods that are called
207bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * before and after execution of each task.  These can be used to
208bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * manipulate the execution environment; for example, reinitializing
209bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * ThreadLocals, gathering statistics, or adding log
210bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * entries. Additionally, method {@link #terminated} can be overridden
211bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * to perform any special processing that needs to be done once the
212bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Executor has fully terminated.
213bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *
214bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>If hook or callback methods throw exceptions, internal worker
215bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * threads may in turn fail and abruptly terminate.</dd>
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <dt>Queue maintenance</dt>
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
219bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <dd> Method {@link #getQueue} allows access to the work queue for
220bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * purposes of monitoring and debugging.  Use of this method for any
221bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * other purpose is strongly discouraged.  Two supplied methods,
222bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * {@link #remove} and {@link #purge} are available to assist in
223bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * storage reclamation when large numbers of queued tasks become
224bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * cancelled.</dd>
225bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *
226bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <dt>Finalization</dt>
227bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *
228bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <dd> A pool that is no longer referenced in a program <em>AND</em>
229bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * has no remaining threads will be {@code shutdown} automatically. If
230bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * you would like to ensure that unreferenced pools are reclaimed even
231bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * if users forget to call {@link #shutdown}, then you must arrange
232bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * that unused threads eventually die, by setting appropriate
2336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * keep-alive times, using a lower bound of zero core threads and/or
2346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * setting {@link #allowCoreThreadTimeOut(boolean)}.  </dd>
235bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *
236bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * </dl>
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> <b>Extension example</b>. Most extensions of this class
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * override one or more of the protected hook methods. For example,
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * here is a subclass that adds a simple pause/resume feature:
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
242bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *  <pre> {@code
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * class PausableThreadPoolExecutor extends ThreadPoolExecutor {
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   private boolean isPaused;
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   private ReentrantLock pauseLock = new ReentrantLock();
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   private Condition unpaused = pauseLock.newCondition();
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   public PausableThreadPoolExecutor(...) { super(...); }
249bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   protected void beforeExecute(Thread t, Runnable r) {
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     super.beforeExecute(t, r);
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     pauseLock.lock();
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     try {
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *       while (isPaused) unpaused.await();
255bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *     } catch (InterruptedException ie) {
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *       t.interrupt();
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     } finally {
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *       pauseLock.unlock();
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     }
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   }
261bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   public void pause() {
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     pauseLock.lock();
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     try {
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *       isPaused = true;
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     } finally {
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *       pauseLock.unlock();
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     }
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   }
270bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   public void resume() {
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     pauseLock.lock();
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     try {
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *       isPaused = false;
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *       unpaused.signalAll();
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     } finally {
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *       pauseLock.unlock();
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     }
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   }
280bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * }}</pre>
281bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @since 1.5
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @author Doug Lea
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class ThreadPoolExecutor extends AbstractExecutorService {
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
287bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * The main pool control state, ctl, is an atomic integer packing
288bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * two conceptual fields
289bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *   workerCount, indicating the effective number of threads
290bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *   runState,    indicating whether running, shutting down etc
291bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
292bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * In order to pack them into one int, we limit workerCount to
293bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * (2^29)-1 (about 500 million) threads rather than (2^31)-1 (2
294bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * billion) otherwise representable. If this is ever an issue in
295bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * the future, the variable can be changed to be an AtomicLong,
296bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * and the shift/mask constants below adjusted. But until the need
297bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * arises, this code is a bit faster and simpler using an int.
298bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
299bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * The workerCount is the number of workers that have been
300bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * permitted to start and not permitted to stop.  The value may be
301bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * transiently different from the actual number of live threads,
302bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * for example when a ThreadFactory fails to create a thread when
303bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * asked, and when exiting threads are still performing
304bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * bookkeeping before terminating. The user-visible pool size is
305bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * reported as the current size of the workers set.
306bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
307bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * The runState provides the main lifecyle control, taking on values:
308bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
309bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *   RUNNING:  Accept new tasks and process queued tasks
310bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *   SHUTDOWN: Don't accept new tasks, but process queued tasks
311bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *   STOP:     Don't accept new tasks, don't process queued tasks,
312bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *             and interrupt in-progress tasks
313bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *   TIDYING:  All tasks have terminated, workerCount is zero,
314bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *             the thread transitioning to state TIDYING
315bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *             will run the terminated() hook method
316bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *   TERMINATED: terminated() has completed
317bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
318bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * The numerical order among these values matters, to allow
319bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * ordered comparisons. The runState monotonically increases over
320bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * time, but need not hit each state. The transitions are:
321bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
322bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * RUNNING -> SHUTDOWN
323bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *    On invocation of shutdown(), perhaps implicitly in finalize()
324bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * (RUNNING or SHUTDOWN) -> STOP
325bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *    On invocation of shutdownNow()
326bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * SHUTDOWN -> TIDYING
327bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *    When both queue and pool are empty
328bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * STOP -> TIDYING
329bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *    When pool is empty
330bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * TIDYING -> TERMINATED
331bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *    When the terminated() hook method has completed
332bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
333bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Threads waiting in awaitTermination() will return when the
334bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * state reaches TERMINATED.
335bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
336bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Detecting the transition from SHUTDOWN to TIDYING is less
337bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * straightforward than you'd like because the queue may become
338bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * empty after non-empty and vice versa during SHUTDOWN state, but
339bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * we can only terminate if, after seeing that it is empty, we see
340bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * that workerCount is 0 (which sometimes entails a recheck -- see
341bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * below).
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
343bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
344bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private static final int COUNT_BITS = Integer.SIZE - 3;
345bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;
346bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
347bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    // runState is stored in the high-order bits
348bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private static final int RUNNING    = -1 << COUNT_BITS;
349bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private static final int SHUTDOWN   =  0 << COUNT_BITS;
350bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private static final int STOP       =  1 << COUNT_BITS;
351bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private static final int TIDYING    =  2 << COUNT_BITS;
352bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private static final int TERMINATED =  3 << COUNT_BITS;
353bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
354bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    // Packing and unpacking ctl
355bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private static int runStateOf(int c)     { return c & ~CAPACITY; }
356bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private static int workerCountOf(int c)  { return c & CAPACITY; }
357bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private static int ctlOf(int rs, int wc) { return rs | wc; }
358bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
359bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /*
360bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Bit field accessors that don't require unpacking ctl.
361bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * These depend on the bit layout and on workerCount being never negative.
362bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
363bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
364bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private static boolean runStateLessThan(int c, int s) {
365bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return c < s;
366bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
367bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
368bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private static boolean runStateAtLeast(int c, int s) {
369bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return c >= s;
370bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
371bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
372bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private static boolean isRunning(int c) {
373bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return c < SHUTDOWN;
374bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
377bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Attempt to CAS-increment the workerCount field of ctl.
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
379bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private boolean compareAndIncrementWorkerCount(int expect) {
380bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return ctl.compareAndSet(expect, expect + 1);
381bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
384bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Attempt to CAS-decrement the workerCount field of ctl.
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
386bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private boolean compareAndDecrementWorkerCount(int expect) {
387bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return ctl.compareAndSet(expect, expect - 1);
388bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
391bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Decrements the workerCount field of ctl. This is called only on
392bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * abrupt termination of a thread (see processWorkerExit). Other
393bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * decrements are performed within getTask.
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
395bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private void decrementWorkerCount() {
396bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        do {} while (! compareAndDecrementWorkerCount(ctl.get()));
397bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
400bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * The queue used for holding tasks and handing off to worker
401bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * threads.  We do not require that workQueue.poll() returning
402bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * null necessarily means that workQueue.isEmpty(), so rely
403bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * solely on isEmpty to see if the queue is empty (which we must
404bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * do for example when deciding whether to transition from
405bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * SHUTDOWN to TIDYING).  This accommodates special-purpose
406bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * queues such as DelayQueues for which poll() is allowed to
407bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * return null even if it may later return non-null when delays
408bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * expire.
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
410bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private final BlockingQueue<Runnable> workQueue;
411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
413bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Lock held on access to workers set and related bookkeeping.
414bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * While we could use a concurrent set of some sort, it turns out
415bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * to be generally preferable to use a lock. Among the reasons is
416bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * that this serializes interruptIdleWorkers, which avoids
417bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * unnecessary interrupt storms, especially during shutdown.
418bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Otherwise exiting threads would concurrently interrupt those
419bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * that have not yet interrupted. It also simplifies some of the
420bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * associated statistics bookkeeping of largestPoolSize etc. We
421bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * also hold mainLock on shutdown and shutdownNow, for the sake of
422bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * ensuring workers set is stable while separately checking
423bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * permission to interrupt and actually interrupting.
424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
425bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private final ReentrantLock mainLock = new ReentrantLock();
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
428bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Set containing all worker threads in pool. Accessed only when
429bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * holding mainLock.
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
431bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private final HashSet<Worker> workers = new HashSet<Worker>();
432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
434bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Wait condition to support awaitTermination
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
436bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private final Condition termination = mainLock.newCondition();
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
439bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Tracks largest attained pool size. Accessed only under
440bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * mainLock.
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
442bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private int largestPoolSize;
443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
445bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Counter for completed tasks. Updated only on termination of
446bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * worker threads. Accessed only under mainLock.
447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
448bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private long completedTaskCount;
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
450bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /*
451bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * All user control parameters are declared as volatiles so that
452bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * ongoing actions are based on freshest values, but without need
453bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * for locking, since no internal invariants depend on them
454bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * changing synchronously with respect to other actions.
455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
457bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
458bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Factory for new threads. All threads are created using this
459bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * factory (via method addWorker).  All callers must be prepared
460bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * for addWorker to fail, which may reflect a system or user's
461bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * policy limiting the number of threads.  Even though it is not
462bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * treated as an error, failure to create threads may result in
463bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * new tasks being rejected or existing ones remaining stuck in
464bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * the queue. On the other hand, no special precautions exist to
465bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * handle OutOfMemoryErrors that might be thrown while trying to
466bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * create threads, since there is generally no recourse from
467bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * within this class.
468bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
469bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private volatile ThreadFactory threadFactory;
470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Handler called when saturated or shutdown in execute.
473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private volatile RejectedExecutionHandler handler;
475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
477bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Timeout in nanoseconds for idle threads waiting for work.
478bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Threads use this timeout when there are more than corePoolSize
4796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * present or if allowCoreThreadTimeOut. Otherwise they wait
4806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * forever for new work.
481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
482bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private volatile long keepAliveTime;
483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
4856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * If false (default), core threads stay alive even when idle.
4866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * If true, core threads use keepAliveTime to time out waiting
4876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * for work.
4886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
4896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    private volatile boolean allowCoreThreadTimeOut;
4906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
4916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
492bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Core pool size is the minimum number of workers to keep alive
4936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * (and not allow to time out etc) unless allowCoreThreadTimeOut
4946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * is set, in which case the minimum is zero.
495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
496bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private volatile int corePoolSize;
497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
499bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Maximum pool size. Note that the actual maximum is internally
500bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * bounded by CAPACITY.
501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
502bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private volatile int maximumPoolSize;
503bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The default rejected execution handler
506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final RejectedExecutionHandler defaultHandler =
508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        new AbortPolicy();
509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
511bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Permission required for callers of shutdown and shutdownNow.
512bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * We additionally require (see checkShutdownAccess) that callers
513bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * have permission to actually interrupt threads in the worker set
514bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * (as governed by Thread.interrupt, which relies on
515bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * ThreadGroup.checkAccess, which in turn relies on
516bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * SecurityManager.checkAccess). Shutdowns are attempted only if
517bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * these checks pass.
518bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
519bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * All actual invocations of Thread.interrupt (see
520bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * interruptIdleWorkers and interruptWorkers) ignore
521bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * SecurityExceptions, meaning that the attempted interrupts
522bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * silently fail. In the case of shutdown, they should not fail
523bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * unless the SecurityManager has inconsistent policies, sometimes
524bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * allowing access to a thread and sometimes not. In such cases,
525bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * failure to actually interrupt threads may disable or delay full
526bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * termination. Other uses of interruptIdleWorkers are advisory,
527bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * and failure to actually interrupt will merely delay response to
528bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * configuration changes so is not handled exceptionally.
529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
530bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private static final RuntimePermission shutdownPerm =
531bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        new RuntimePermission("modifyThread");
532bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
533bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
534bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Class Worker mainly maintains interrupt control state for
535bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * threads running tasks, along with other minor bookkeeping.
536bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * This class opportunistically extends AbstractQueuedSynchronizer
537bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * to simplify acquiring and releasing a lock surrounding each
538bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * task execution.  This protects against interrupts that are
539bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * intended to wake up a worker thread waiting for a task from
540bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * instead interrupting a task being run.  We implement a simple
541bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * non-reentrant mutual exclusion lock rather than use ReentrantLock
542bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * because we do not want worker tasks to be able to reacquire the
543bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * lock when they invoke pool control methods like setCorePoolSize.
544bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
545bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private final class Worker
546bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        extends AbstractQueuedSynchronizer
547bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        implements Runnable
548bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    {
549bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        /**
550bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         * This class will never be serialized, but we provide a
551bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         * serialVersionUID to suppress a javac warning.
552bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         */
553bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        private static final long serialVersionUID = 6138294804551838833L;
554bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
555bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        /** Thread this worker is running in.  Null if factory fails. */
556bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        final Thread thread;
557bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        /** Initial task to run.  Possibly null. */
558bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        Runnable firstTask;
559bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        /** Per-thread task counter */
560bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        volatile long completedTasks;
561bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
562bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        /**
563bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         * Creates with given first task and thread from ThreadFactory.
564bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         * @param firstTask the first task (null if none)
565bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         */
566bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        Worker(Runnable firstTask) {
567bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            this.firstTask = firstTask;
568bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            this.thread = getThreadFactory().newThread(this);
569bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
570bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
571bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        /** Delegates main run loop to outer runWorker  */
572bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        public void run() {
573bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            runWorker(this);
574bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
575bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
576bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        // Lock methods
577bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        //
578bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        // The value 0 represents the unlocked state.
579bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        // The value 1 represents the locked state.
580bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
581bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        protected boolean isHeldExclusively() {
582bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            return getState() == 1;
583bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
584bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
585bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        protected boolean tryAcquire(int unused) {
586bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (compareAndSetState(0, 1)) {
587bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                setExclusiveOwnerThread(Thread.currentThread());
588bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                return true;
589bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            }
590bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            return false;
591bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
592bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
593bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        protected boolean tryRelease(int unused) {
594bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            setExclusiveOwnerThread(null);
595bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            setState(0);
596bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            return true;
597bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
598bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
599bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        public void lock()        { acquire(1); }
600bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        public boolean tryLock()  { return tryAcquire(1); }
601bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        public void unlock()      { release(1); }
602bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        public boolean isLocked() { return isHeldExclusively(); }
603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
605bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /*
606bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Methods for setting control state
607bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
608bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
610bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Transitions runState to given target, or leaves it alone if
611bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * already at least the given target.
612bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
613bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param targetState the desired state, either SHUTDOWN or STOP
614bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        (but not TIDYING or TERMINATED -- use tryTerminate for that)
615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
616bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private void advanceRunState(int targetState) {
617bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        for (;;) {
618bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            int c = ctl.get();
619bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (runStateAtLeast(c, targetState) ||
620bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
621bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                break;
622bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
626bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Transitions to TERMINATED state if either (SHUTDOWN and pool
627bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * and queue empty) or (STOP and pool empty).  If otherwise
628bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * eligible to terminate but workerCount is nonzero, interrupts an
629bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * idle worker to ensure that shutdown signals propagate. This
630bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * method must be called following any action that might make
631bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * termination possible -- reducing worker count or removing tasks
632bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * from the queue during shutdown. The method is non-private to
633bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * allow access from ScheduledThreadPoolExecutor.
634bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
635bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    final void tryTerminate() {
636bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        for (;;) {
637bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            int c = ctl.get();
638bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (isRunning(c) ||
639bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                runStateAtLeast(c, TIDYING) ||
640bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
641bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                return;
642bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (workerCountOf(c) != 0) { // Eligible to terminate
643bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                interruptIdleWorkers(ONLY_ONE);
644bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                return;
645bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            }
646bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
647bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            final ReentrantLock mainLock = this.mainLock;
648bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            mainLock.lock();
649bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            try {
650bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
651bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    try {
652bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                        terminated();
653bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    } finally {
654bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                        ctl.set(ctlOf(TERMINATED, 0));
655bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                        termination.signalAll();
656bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    }
657bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    return;
658bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                }
659bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            } finally {
660bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                mainLock.unlock();
661bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            }
662bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            // else retry on failed CAS
663bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
664bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
665bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
666bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /*
667bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Methods for controlling interrupts to worker threads.
668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
669bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
670bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
671bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * If there is a security manager, makes sure caller has
672bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * permission to shut down threads in general (see shutdownPerm).
673bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * If this passes, additionally makes sure the caller is allowed
674bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * to interrupt each worker thread. This might not be true even if
675bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * first check passed, if the SecurityManager treats some threads
676bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * specially.
677bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
678bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private void checkShutdownAccess() {
679bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        SecurityManager security = System.getSecurityManager();
680bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        if (security != null) {
681bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            security.checkPermission(shutdownPerm);
682bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            final ReentrantLock mainLock = this.mainLock;
683bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            mainLock.lock();
684bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            try {
685bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                for (Worker w : workers)
686bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    security.checkAccess(w.thread);
687bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            } finally {
688bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                mainLock.unlock();
689bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            }
690bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
691bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
692bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
693bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
694bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Interrupts all threads, even if active. Ignores SecurityExceptions
695bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * (in which case some threads may remain uninterrupted).
696bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
697bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private void interruptWorkers() {
698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final ReentrantLock mainLock = this.mainLock;
699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        mainLock.lock();
700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
701bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            for (Worker w : workers) {
702bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                try {
703bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    w.thread.interrupt();
704bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                } catch (SecurityException ignore) {
705bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                }
706bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            }
707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            mainLock.unlock();
709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
713bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Interrupts threads that might be waiting for tasks (as
714bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * indicated by not being locked) so they can check for
715bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * termination or configuration changes. Ignores
716bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * SecurityExceptions (in which case some threads may remain
717bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * uninterrupted).
718bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
719bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param onlyOne If true, interrupt at most one worker. This is
720bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * called only from tryTerminate when termination is otherwise
721bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * enabled but there are still other workers.  In this case, at
722bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * most one waiting worker is interrupted to propagate shutdown
723bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * signals in case all threads are currently waiting.
724bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Interrupting any arbitrary thread ensures that newly arriving
725bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * workers since shutdown began will also eventually exit.
726bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * To guarantee eventual termination, it suffices to always
727bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * interrupt only one idle worker, but shutdown() interrupts all
728bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * idle workers so that redundant workers exit promptly, not
729bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * waiting for a straggler task to finish.
730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
731bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private void interruptIdleWorkers(boolean onlyOne) {
732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final ReentrantLock mainLock = this.mainLock;
733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        mainLock.lock();
734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
735bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            for (Worker w : workers) {
736bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                Thread t = w.thread;
737bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                if (!t.isInterrupted() && w.tryLock()) {
738bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    try {
739bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                        t.interrupt();
740bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    } catch (SecurityException ignore) {
741bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    } finally {
742bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                        w.unlock();
743bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    }
744bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                }
745bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                if (onlyOne)
746bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    break;
747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            mainLock.unlock();
750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
753bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
754bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Common form of interruptIdleWorkers, to avoid having to
755bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * remember what the boolean argument means.
756bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
757bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private void interruptIdleWorkers() {
758bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        interruptIdleWorkers(false);
759bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
760bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
761bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private static final boolean ONLY_ONE = true;
762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
764bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Ensures that unless the pool is stopping, the current thread
765bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * does not have its interrupt set. This requires a double-check
766bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * of state in case the interrupt was cleared concurrently with a
767bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * shutdownNow -- if so, the interrupt is re-enabled.
768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
769bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private void clearInterruptsForTaskRun() {
770bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        if (runStateLessThan(ctl.get(), STOP) &&
771bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            Thread.interrupted() &&
772bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            runStateAtLeast(ctl.get(), STOP))
773bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            Thread.currentThread().interrupt();
774bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
776bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /*
777bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Misc utilities, most of which are also exported to
778bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * ScheduledThreadPoolExecutor
779bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
781bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
782bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Invokes the rejected execution handler for the given command.
783bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Package-protected for use by ScheduledThreadPoolExecutor.
784bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
785bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    final void reject(Runnable command) {
786bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        handler.rejectedExecution(command, this);
787bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
789bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
790bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Performs any further cleanup following run state transition on
791bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * invocation of shutdown.  A no-op here, but used by
792bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * ScheduledThreadPoolExecutor to cancel delayed tasks.
793bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
794bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    void onShutdown() {
795bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
796bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
797bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
798bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * State check needed by ScheduledThreadPoolExecutor to
799bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * enable running tasks during shutdown.
800bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
801bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param shutdownOK true if should return true if SHUTDOWN
802bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
803bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    final boolean isRunningOrShutdown(boolean shutdownOK) {
804bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        int rs = runStateOf(ctl.get());
805bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return rs == RUNNING || (rs == SHUTDOWN && shutdownOK);
806bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
807bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
808bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
809bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Drains the task queue into a new list, normally using
810bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * drainTo. But if the queue is a DelayQueue or any other kind of
811bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * queue for which poll or drainTo may fail to remove some
812bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * elements, it deletes them one by one.
813bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
814bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private List<Runnable> drainQueue() {
815bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        BlockingQueue<Runnable> q = workQueue;
816bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        List<Runnable> taskList = new ArrayList<Runnable>();
817bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        q.drainTo(taskList);
818bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        if (!q.isEmpty()) {
819bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            for (Runnable r : q.toArray(new Runnable[0])) {
820bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                if (q.remove(r))
821bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    taskList.add(r);
822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
824bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return taskList;
825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
827bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /*
828bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Methods for creating, running and cleaning up after workers
829bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
830bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
832bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Checks if a new worker can be added with respect to current
833bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * pool state and the given bound (either core or maximum). If so,
834bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * the worker count is adjusted accordingly, and, if possible, a
835bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * new worker is created and started running firstTask as its
836bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * first task. This method returns false if the pool is stopped or
837bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * eligible to shut down. It also returns false if the thread
838bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * factory fails to create a thread when asked, which requires a
839bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * backout of workerCount, and a recheck for termination, in case
840bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * the existence of this worker was holding up termination.
841bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
842bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param firstTask the task the new thread should run first (or
843bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * null if none). Workers are created with an initial first task
844bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * (in method execute()) to bypass queuing when there are fewer
845bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * than corePoolSize threads (in which case we always start one),
846bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * or when the queue is full (in which case we must bypass queue).
847bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Initially idle threads are usually created via
848bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * prestartCoreThread or to replace other dying workers.
849bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
850bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param core if true use corePoolSize as bound, else
851bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * maximumPoolSize. (A boolean indicator is used here rather than a
852bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * value to ensure reads of fresh values after checking other pool
853bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * state).
854bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return true if successful
855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
856bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private boolean addWorker(Runnable firstTask, boolean core) {
857bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        retry:
858bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        for (;;) {
859bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            int c = ctl.get();
860bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            int rs = runStateOf(c);
861bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
862bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            // Check if queue empty only if necessary.
863bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (rs >= SHUTDOWN &&
864bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                ! (rs == SHUTDOWN &&
865bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                   firstTask == null &&
866bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                   ! workQueue.isEmpty()))
867bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                return false;
868bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
869bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            for (;;) {
870bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                int wc = workerCountOf(c);
871bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                if (wc >= CAPACITY ||
872bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    wc >= (core ? corePoolSize : maximumPoolSize))
873bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    return false;
874bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                if (compareAndIncrementWorkerCount(c))
875bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    break retry;
876bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                c = ctl.get();  // Re-read ctl
877bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                if (runStateOf(c) != rs)
878bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    continue retry;
879bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                // else CAS failed due to workerCount change; retry inner loop
880bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            }
881bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
882bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
883bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        Worker w = new Worker(firstTask);
884bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        Thread t = w.thread;
885bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final ReentrantLock mainLock = this.mainLock;
887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        mainLock.lock();
888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
889bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            // Recheck while holding lock.
890bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            // Back out on ThreadFactory failure or if
891bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            // shut down before lock acquired.
892bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            int c = ctl.get();
893bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            int rs = runStateOf(c);
894bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
895bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (t == null ||
896bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                (rs >= SHUTDOWN &&
897bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                 ! (rs == SHUTDOWN &&
898bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    firstTask == null))) {
899bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                decrementWorkerCount();
900bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                tryTerminate();
901bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                return false;
902bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            }
903bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
904bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            workers.add(w);
905bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
906bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            int s = workers.size();
907bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (s > largestPoolSize)
908bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                largestPoolSize = s;
909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            mainLock.unlock();
911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
912bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
913bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        t.start();
914bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        // It is possible (but unlikely) for a thread to have been
915bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        // added to workers, but not yet started, during transition to
916bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        // STOP, which could result in a rare missed interrupt,
917bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        // because Thread.interrupt is not guaranteed to have any effect
918bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        // on a non-yet-started Thread (see Thread#interrupt).
919bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        if (runStateOf(ctl.get()) == STOP && ! t.isInterrupted())
920bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            t.interrupt();
921bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
922bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return true;
923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
926bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Performs cleanup and bookkeeping for a dying worker. Called
927bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * only from worker threads. Unless completedAbruptly is set,
928bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * assumes that workerCount has already been adjusted to account
929bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * for exit.  This method removes thread from worker set, and
930bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * possibly terminates the pool or replaces the worker if either
931bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * it exited due to user task exception or if fewer than
932bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * corePoolSize workers are running or queue is non-empty but
933bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * there are no workers.
934bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param w the worker
936bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param completedAbruptly if the worker died due to user exception
937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
938bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private void processWorkerExit(Worker w, boolean completedAbruptly) {
939bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
940bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            decrementWorkerCount();
941bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final ReentrantLock mainLock = this.mainLock;
943adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        mainLock.lock();
944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            completedTaskCount += w.completedTasks;
946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            workers.remove(w);
947adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
948adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            mainLock.unlock();
949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
950adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
951bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        tryTerminate();
952bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
953bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        int c = ctl.get();
954bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        if (runStateLessThan(c, STOP)) {
955bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (!completedAbruptly) {
9566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
957bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                if (min == 0 && ! workQueue.isEmpty())
958bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    min = 1;
959bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                if (workerCountOf(c) >= min)
960bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    return; // replacement not needed
961bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            }
962bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            addWorker(null, false);
963bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
964adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
965adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
966adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
967bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Performs blocking or timed wait for a task, depending on
968bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * current configuration settings, or returns null if this worker
969bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * must exit because of any of:
970bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * 1. There are more than maximumPoolSize workers (due to
971bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *    a call to setMaximumPoolSize).
972bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * 2. The pool is stopped.
973bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * 3. The pool is shutdown and the queue is empty.
974bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * 4. This worker timed out waiting for a task, and timed-out
975bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *    workers are subject to termination (that is,
9766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *    {@code allowCoreThreadTimeOut || workerCount > corePoolSize})
977bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *    both before and after the timed wait.
978bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
979bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return task, or null if the worker must exit, in which case
980bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         workerCount is decremented
981adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
982bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private Runnable getTask() {
983bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        boolean timedOut = false; // Did the last poll() time out?
984adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
985bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        retry:
986bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        for (;;) {
987bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            int c = ctl.get();
988bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            int rs = runStateOf(c);
989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
990bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            // Check if queue empty only if necessary.
991bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
992bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                decrementWorkerCount();
993bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                return null;
994bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            }
995adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
996bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            boolean timed;      // Are workers subject to culling?
997adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
998bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            for (;;) {
999bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                int wc = workerCountOf(c);
10006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                timed = allowCoreThreadTimeOut || wc > corePoolSize;
1001adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1002bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                if (wc <= maximumPoolSize && ! (timedOut && timed))
1003bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    break;
1004bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                if (compareAndDecrementWorkerCount(c))
1005bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    return null;
1006bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                c = ctl.get();  // Re-read ctl
1007bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                if (runStateOf(c) != rs)
1008bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    continue retry;
1009bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                // else CAS failed due to workerCount change; retry inner loop
1010adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1011adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1012adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
1013bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                Runnable r = timed ?
1014bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
1015bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    workQueue.take();
1016bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                if (r != null)
1017bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    return r;
1018bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                timedOut = true;
1019bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            } catch (InterruptedException retry) {
1020bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                timedOut = false;
1021adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1022adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1023bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
1024adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1025bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
1026bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Main worker run loop.  Repeatedly gets tasks from queue and
1027bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * executes them, while coping with a number of issues:
1028bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
1029bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * 1. We may start out with an initial task, in which case we
1030bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * don't need to get the first one. Otherwise, as long as pool is
1031bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * running, we get tasks from getTask. If it returns null then the
1032bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * worker exits due to changed pool state or configuration
1033bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * parameters.  Other exits result from exception throws in
1034bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * external code, in which case completedAbruptly holds, which
1035bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * usually leads processWorkerExit to replace this thread.
1036bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
1037bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * 2. Before running any task, the lock is acquired to prevent
1038bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * other pool interrupts while the task is executing, and
1039bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * clearInterruptsForTaskRun called to ensure that unless pool is
1040bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * stopping, this thread does not have its interrupt set.
1041bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
1042bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * 3. Each task run is preceded by a call to beforeExecute, which
1043bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * might throw an exception, in which case we cause thread to die
1044bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * (breaking loop with completedAbruptly true) without processing
1045bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * the task.
1046bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
1047bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * 4. Assuming beforeExecute completes normally, we run the task,
1048bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * gathering any of its thrown exceptions to send to
1049bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * afterExecute. We separately handle RuntimeException, Error
1050bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * (both of which the specs guarantee that we trap) and arbitrary
1051bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Throwables.  Because we cannot rethrow Throwables within
1052bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Runnable.run, we wrap them within Errors on the way out (to the
1053bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * thread's UncaughtExceptionHandler).  Any thrown exception also
1054bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * conservatively causes thread to die.
1055bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
1056bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * 5. After task.run completes, we call afterExecute, which may
1057bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * also throw an exception, which will also cause thread to
1058bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * die. According to JLS Sec 14.20, this exception is the one that
1059bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * will be in effect even if task.run throws.
1060bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
1061bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * The net effect of the exception mechanics is that afterExecute
1062bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * and the thread's UncaughtExceptionHandler have as accurate
1063bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * information as we can provide about any problems encountered by
1064bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * user code.
1065bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
1066bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param w the worker
1067bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
1068bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    final void runWorker(Worker w) {
1069bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        Runnable task = w.firstTask;
1070bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        w.firstTask = null;
1071bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        boolean completedAbruptly = true;
1072bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        try {
1073bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            while (task != null || (task = getTask()) != null) {
1074bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                w.lock();
1075bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                clearInterruptsForTaskRun();
1076bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                try {
1077bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    beforeExecute(w.thread, task);
1078bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    Throwable thrown = null;
1079bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    try {
1080bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                        task.run();
1081bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    } catch (RuntimeException x) {
1082bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                        thrown = x; throw x;
1083bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    } catch (Error x) {
1084bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                        thrown = x; throw x;
1085bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    } catch (Throwable x) {
1086bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                        thrown = x; throw new Error(x);
1087bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    } finally {
1088bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                        afterExecute(task, thrown);
1089bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    }
1090bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                } finally {
1091bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    task = null;
1092bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    w.completedTasks++;
1093bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    w.unlock();
1094adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1095adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1096bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            completedAbruptly = false;
1097bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        } finally {
1098bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            processWorkerExit(w, completedAbruptly);
1099adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1102bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    // Public constructors and methods
1103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1105bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Creates a new {@code ThreadPoolExecutor} with the given initial
1106bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * parameters and default thread factory and rejected execution handler.
1107bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * It may be more convenient to use one of the {@link Executors} factory
1108bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * methods instead of this general purpose constructor.
1109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
1110bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param corePoolSize the number of threads to keep in the pool, even
11116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
1112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param maximumPoolSize the maximum number of threads to allow in the
1113bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        pool
1114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param keepAliveTime when the number of threads is greater than
1115bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        the core, this is the maximum time that excess idle threads
1116bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        will wait for new tasks before terminating.
1117bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param unit the time unit for the {@code keepAliveTime} argument
1118bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param workQueue the queue to use for holding tasks before they are
1119bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        executed.  This queue will hold only the {@code Runnable}
1120bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        tasks submitted by the {@code execute} method.
1121bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws IllegalArgumentException if one of the following holds:<br>
1122bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         {@code corePoolSize < 0}<br>
1123bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         {@code keepAliveTime < 0}<br>
1124bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         {@code maximumPoolSize <= 0}<br>
1125bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         {@code maximumPoolSize < corePoolSize}
1126bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws NullPointerException if {@code workQueue} is null
1127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public ThreadPoolExecutor(int corePoolSize,
1129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                              int maximumPoolSize,
1130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                              long keepAliveTime,
1131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                              TimeUnit unit,
1132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                              BlockingQueue<Runnable> workQueue) {
1133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
1134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             Executors.defaultThreadFactory(), defaultHandler);
1135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1138bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Creates a new {@code ThreadPoolExecutor} with the given initial
1139bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * parameters and default rejected execution handler.
1140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
1141bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param corePoolSize the number of threads to keep in the pool, even
11426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
1143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param maximumPoolSize the maximum number of threads to allow in the
1144bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        pool
1145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param keepAliveTime when the number of threads is greater than
1146bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        the core, this is the maximum time that excess idle threads
1147bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        will wait for new tasks before terminating.
1148bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param unit the time unit for the {@code keepAliveTime} argument
1149bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param workQueue the queue to use for holding tasks before they are
1150bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        executed.  This queue will hold only the {@code Runnable}
1151bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        tasks submitted by the {@code execute} method.
1152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param threadFactory the factory to use when the executor
1153bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        creates a new thread
1154bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws IllegalArgumentException if one of the following holds:<br>
1155bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         {@code corePoolSize < 0}<br>
1156bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         {@code keepAliveTime < 0}<br>
1157bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         {@code maximumPoolSize <= 0}<br>
1158bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         {@code maximumPoolSize < corePoolSize}
1159bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws NullPointerException if {@code workQueue}
1160bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         or {@code threadFactory} is null
1161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public ThreadPoolExecutor(int corePoolSize,
1163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                              int maximumPoolSize,
1164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                              long keepAliveTime,
1165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                              TimeUnit unit,
1166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                              BlockingQueue<Runnable> workQueue,
1167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                              ThreadFactory threadFactory) {
1168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
1169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             threadFactory, defaultHandler);
1170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1173bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Creates a new {@code ThreadPoolExecutor} with the given initial
1174bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * parameters and default thread factory.
1175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
1176bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param corePoolSize the number of threads to keep in the pool, even
11776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
1178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param maximumPoolSize the maximum number of threads to allow in the
1179bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        pool
1180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param keepAliveTime when the number of threads is greater than
1181bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        the core, this is the maximum time that excess idle threads
1182bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        will wait for new tasks before terminating.
1183bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param unit the time unit for the {@code keepAliveTime} argument
1184bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param workQueue the queue to use for holding tasks before they are
1185bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        executed.  This queue will hold only the {@code Runnable}
1186bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        tasks submitted by the {@code execute} method.
1187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param handler the handler to use when execution is blocked
1188bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        because the thread bounds and queue capacities are reached
1189bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws IllegalArgumentException if one of the following holds:<br>
1190bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         {@code corePoolSize < 0}<br>
1191bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         {@code keepAliveTime < 0}<br>
1192bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         {@code maximumPoolSize <= 0}<br>
1193bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         {@code maximumPoolSize < corePoolSize}
1194bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws NullPointerException if {@code workQueue}
1195bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         or {@code handler} is null
1196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public ThreadPoolExecutor(int corePoolSize,
1198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                              int maximumPoolSize,
1199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                              long keepAliveTime,
1200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                              TimeUnit unit,
1201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                              BlockingQueue<Runnable> workQueue,
1202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                              RejectedExecutionHandler handler) {
1203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
1204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             Executors.defaultThreadFactory(), handler);
1205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1208bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Creates a new {@code ThreadPoolExecutor} with the given initial
1209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * parameters.
1210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
1211bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param corePoolSize the number of threads to keep in the pool, even
12126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
1213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param maximumPoolSize the maximum number of threads to allow in the
1214bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        pool
1215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param keepAliveTime when the number of threads is greater than
1216bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        the core, this is the maximum time that excess idle threads
1217bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        will wait for new tasks before terminating.
1218bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param unit the time unit for the {@code keepAliveTime} argument
1219bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param workQueue the queue to use for holding tasks before they are
1220bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        executed.  This queue will hold only the {@code Runnable}
1221bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        tasks submitted by the {@code execute} method.
1222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param threadFactory the factory to use when the executor
1223bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        creates a new thread
1224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param handler the handler to use when execution is blocked
1225bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        because the thread bounds and queue capacities are reached
1226bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws IllegalArgumentException if one of the following holds:<br>
1227bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         {@code corePoolSize < 0}<br>
1228bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         {@code keepAliveTime < 0}<br>
1229bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         {@code maximumPoolSize <= 0}<br>
1230bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         {@code maximumPoolSize < corePoolSize}
1231bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws NullPointerException if {@code workQueue}
1232bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         or {@code threadFactory} or {@code handler} is null
1233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public ThreadPoolExecutor(int corePoolSize,
1235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                              int maximumPoolSize,
1236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                              long keepAliveTime,
1237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                              TimeUnit unit,
1238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                              BlockingQueue<Runnable> workQueue,
1239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                              ThreadFactory threadFactory,
1240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                              RejectedExecutionHandler handler) {
1241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (corePoolSize < 0 ||
1242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            maximumPoolSize <= 0 ||
1243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            maximumPoolSize < corePoolSize ||
1244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            keepAliveTime < 0)
1245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IllegalArgumentException();
1246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (workQueue == null || threadFactory == null || handler == null)
1247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new NullPointerException();
1248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.corePoolSize = corePoolSize;
1249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.maximumPoolSize = maximumPoolSize;
1250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.workQueue = workQueue;
1251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.keepAliveTime = unit.toNanos(keepAliveTime);
1252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.threadFactory = threadFactory;
1253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.handler = handler;
1254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Executes the given task sometime in the future.  The task
1258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * may execute in a new thread or in an existing pooled thread.
1259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
1260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If the task cannot be submitted for execution, either because this
1261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * executor has been shutdown or because its capacity has been reached,
1262bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * the task is handled by the current {@code RejectedExecutionHandler}.
1263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
1264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param command the task to execute
1265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws RejectedExecutionException at discretion of
1266bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         {@code RejectedExecutionHandler}, if the task
1267bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         cannot be accepted for execution
1268bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws NullPointerException if {@code command} is null
1269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void execute(Runnable command) {
1271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (command == null)
1272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new NullPointerException();
1273bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        /*
1274bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         * Proceed in 3 steps:
1275bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         *
1276bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         * 1. If fewer than corePoolSize threads are running, try to
1277bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         * start a new thread with the given command as its first
1278bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         * task.  The call to addWorker atomically checks runState and
1279bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         * workerCount, and so prevents false alarms that would add
1280bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         * threads when it shouldn't, by returning false.
1281bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         *
1282bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         * 2. If a task can be successfully queued, then we still need
1283bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         * to double-check whether we should have added a thread
1284bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         * (because existing ones died since last checking) or that
1285bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         * the pool shut down since entry into this method. So we
1286bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         * recheck state and if necessary roll back the enqueuing if
1287bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         * stopped, or start a new thread if there are none.
1288bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         *
1289bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         * 3. If we cannot queue task, then we try to add a new
1290bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         * thread.  If it fails, we know we are shut down or saturated
1291bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         * and so reject the task.
1292bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         */
1293bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        int c = ctl.get();
1294bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        if (workerCountOf(c) < corePoolSize) {
1295bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (addWorker(command, true))
1296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return;
1297bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            c = ctl.get();
1298bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
1299bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        if (isRunning(c) && workQueue.offer(command)) {
1300bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            int recheck = ctl.get();
1301bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (! isRunning(recheck) && remove(command))
1302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                reject(command);
1303bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            else if (workerCountOf(recheck) == 0)
1304bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                addWorker(null, false);
1305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1306bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        else if (!addWorker(command, false))
1307bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            reject(command);
1308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Initiates an orderly shutdown in which previously submitted
1312bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * tasks are executed, but no new tasks will be accepted.
1313bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Invocation has no additional effect if already shut down.
1314bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
1315bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>This method does not wait for previously submitted tasks to
1316bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * complete execution.  Use {@link #awaitTermination awaitTermination}
1317bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * to do that.
1318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void shutdown() {
1320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final ReentrantLock mainLock = this.mainLock;
1321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        mainLock.lock();
1322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
1323bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            checkShutdownAccess();
1324bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            advanceRunState(SHUTDOWN);
1325bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            interruptIdleWorkers();
1326bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            onShutdown(); // hook for ScheduledThreadPoolExecutor
1327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
1328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            mainLock.unlock();
1329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1330bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        tryTerminate();
1331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Attempts to stop all actively executing tasks, halts the
1335bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * processing of waiting tasks, and returns a list of the tasks
1336bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * that were awaiting execution. These tasks are drained (removed)
1337bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * from the task queue upon return from this method.
1338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
1339bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>This method does not wait for actively executing tasks to
1340bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * terminate.  Use {@link #awaitTermination awaitTermination} to
1341bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * do that.
1342bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
1343bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>There are no guarantees beyond best-effort attempts to stop
1344bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * processing actively executing tasks.  This implementation
1345bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * cancels tasks via {@link Thread#interrupt}, so any task that
1346bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * fails to respond to interrupts may never terminate.
1347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public List<Runnable> shutdownNow() {
1349bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        List<Runnable> tasks;
1350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final ReentrantLock mainLock = this.mainLock;
1351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        mainLock.lock();
1352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
1353bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            checkShutdownAccess();
1354bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            advanceRunState(STOP);
1355bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            interruptWorkers();
1356bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            tasks = drainQueue();
1357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
1358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            mainLock.unlock();
1359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1360bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        tryTerminate();
1361bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return tasks;
1362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isShutdown() {
1365bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return ! isRunning(ctl.get());
1366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1368bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
1369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns true if this executor is in the process of terminating
1370bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * after {@link #shutdown} or {@link #shutdownNow} but has not
1371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * completely terminated.  This method may be useful for
1372bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * debugging. A return of {@code true} reported a sufficient
1373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * period after shutdown may indicate that submitted tasks have
1374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * ignored or suppressed interruption, causing this executor not
1375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * to properly terminate.
1376bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
1377bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return true if terminating but not yet terminated
1378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isTerminating() {
1380bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        int c = ctl.get();
1381bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return ! isRunning(c) && runStateLessThan(c, TERMINATED);
1382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isTerminated() {
1385bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return runStateAtLeast(ctl.get(), TERMINATED);
1386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean awaitTermination(long timeout, TimeUnit unit)
1389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throws InterruptedException {
1390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        long nanos = unit.toNanos(timeout);
1391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final ReentrantLock mainLock = this.mainLock;
1392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        mainLock.lock();
1393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
1394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (;;) {
1395bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                if (runStateAtLeast(ctl.get(), TERMINATED))
1396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return true;
1397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (nanos <= 0)
1398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return false;
1399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                nanos = termination.awaitNanos(nanos);
1400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
1402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            mainLock.unlock();
1403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1407bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Invokes {@code shutdown} when this executor is no longer
1408bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * referenced and it has no threads.
1409bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
14108eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    protected void finalize() {
14118eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        shutdown();
1412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the thread factory used to create new threads.
1416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
1417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param threadFactory the new thread factory
1418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException if threadFactory is null
1419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #getThreadFactory
1420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setThreadFactory(ThreadFactory threadFactory) {
1422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (threadFactory == null)
1423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new NullPointerException();
1424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.threadFactory = threadFactory;
1425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the thread factory used to create new threads.
1429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
1430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the current thread factory
1431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #setThreadFactory
1432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public ThreadFactory getThreadFactory() {
1434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return threadFactory;
1435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets a new handler for unexecutable tasks.
1439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
1440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param handler the new handler
1441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException if handler is null
1442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #getRejectedExecutionHandler
1443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setRejectedExecutionHandler(RejectedExecutionHandler handler) {
1445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (handler == null)
1446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new NullPointerException();
1447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.handler = handler;
1448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the current handler for unexecutable tasks.
1452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
1453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the current handler
1454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #setRejectedExecutionHandler
1455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public RejectedExecutionHandler getRejectedExecutionHandler() {
1457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return handler;
1458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the core number of threads.  This overrides any value set
1462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * in the constructor.  If the new value is smaller than the
1463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * current value, excess existing threads will be terminated when
1464bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * they next become idle.  If larger, new threads will, if needed,
1465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * be started to execute any queued tasks.
1466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
1467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param corePoolSize the new core size
1468bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws IllegalArgumentException if {@code corePoolSize < 0}
1469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #getCorePoolSize
1470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setCorePoolSize(int corePoolSize) {
1472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (corePoolSize < 0)
1473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IllegalArgumentException();
1474bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        int delta = corePoolSize - this.corePoolSize;
1475bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        this.corePoolSize = corePoolSize;
1476bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        if (workerCountOf(ctl.get()) > corePoolSize)
1477bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            interruptIdleWorkers();
1478bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        else if (delta > 0) {
1479bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            // We don't really know how many new threads are "needed".
1480bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            // As a heuristic, prestart enough new workers (up to new
1481bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            // core size) to handle the current number of tasks in
1482bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            // queue, but stop if queue becomes empty while doing so.
1483bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            int k = Math.min(delta, workQueue.size());
1484bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            while (k-- > 0 && addWorker(null, true)) {
1485bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                if (workQueue.isEmpty())
1486bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    break;
1487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the core number of threads.
1493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
1494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the core number of threads
1495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #setCorePoolSize
1496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getCorePoolSize() {
1498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return corePoolSize;
1499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Starts a core thread, causing it to idly wait for work. This
1503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * overrides the default policy of starting core threads only when
1504bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * new tasks are executed. This method will return {@code false}
1505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * if all core threads have already been started.
1506bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
1507bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return {@code true} if a thread was started
1508bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
1509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean prestartCoreThread() {
1510bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return workerCountOf(ctl.get()) < corePoolSize &&
1511bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            addWorker(null, true);
1512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1515a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson     * Same as prestartCoreThread except arranges that at least one
1516a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson     * thread is started even if corePoolSize is 0.
1517a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson     */
1518a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson    void ensurePrestart() {
1519a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson        int wc = workerCountOf(ctl.get());
1520a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson        if (wc < corePoolSize)
1521a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            addWorker(null, true);
1522a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson        else if (wc == 0)
1523a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson            addWorker(null, false);
1524a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson    }
1525a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson
1526a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson    /**
1527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Starts all core threads, causing them to idly wait for work. This
1528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * overrides the default policy of starting core threads only when
1529bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * new tasks are executed.
1530bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
1531bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return the number of threads started
1532bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
1533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int prestartAllCoreThreads() {
1534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int n = 0;
1535bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        while (addWorker(null, true))
1536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ++n;
1537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return n;
1538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
15416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Returns true if this pool allows core threads to time out and
15426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * terminate if no tasks arrive within the keepAlive time, being
15436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * replaced if needed when new tasks arrive. When true, the same
15446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * keep-alive policy applying to non-core threads applies also to
15456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * core threads. When false (the default), core threads are never
15466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * terminated due to lack of incoming tasks.
15476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
15486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @return {@code true} if core threads are allowed to time out,
15496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         else {@code false}
15506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
15516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @since 1.6
15526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
15536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    public boolean allowsCoreThreadTimeOut() {
15546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        return allowCoreThreadTimeOut;
15556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
15566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
15576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
15586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Sets the policy governing whether core threads may time out and
15596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * terminate if no tasks arrive within the keep-alive time, being
15606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * replaced if needed when new tasks arrive. When false, core
15616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * threads are never terminated due to lack of incoming
15626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * tasks. When true, the same keep-alive policy applying to
15636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * non-core threads applies also to core threads. To avoid
15646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * continual thread replacement, the keep-alive time must be
15656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * greater than zero when setting {@code true}. This method
15666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * should in general be called before the pool is actively used.
15676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
15686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param value {@code true} if should time out, else {@code false}
15696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @throws IllegalArgumentException if value is {@code true}
15706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *         and the current keep-alive time is not greater than zero
15716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
15726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @since 1.6
15736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
15746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    public void allowCoreThreadTimeOut(boolean value) {
15756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (value && keepAliveTime <= 0)
15766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
15776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (value != allowCoreThreadTimeOut) {
15786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            allowCoreThreadTimeOut = value;
15796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            if (value)
15806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                interruptIdleWorkers();
15816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        }
15826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
15836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
15846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
1585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the maximum allowed number of threads. This overrides any
1586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * value set in the constructor. If the new value is smaller than
1587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the current value, excess existing threads will be
1588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * terminated when they next become idle.
1589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
1590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param maximumPoolSize the new maximum
1591bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws IllegalArgumentException if the new maximum is
1592bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         less than or equal to zero, or
1593bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         less than the {@linkplain #getCorePoolSize core pool size}
1594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #getMaximumPoolSize
1595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setMaximumPoolSize(int maximumPoolSize) {
1597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (maximumPoolSize <= 0 || maximumPoolSize < corePoolSize)
1598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IllegalArgumentException();
1599bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        this.maximumPoolSize = maximumPoolSize;
1600bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        if (workerCountOf(ctl.get()) > maximumPoolSize)
1601bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            interruptIdleWorkers();
1602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the maximum allowed number of threads.
1606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
1607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the maximum allowed number of threads
1608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #setMaximumPoolSize
1609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getMaximumPoolSize() {
1611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return maximumPoolSize;
1612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the time limit for which threads may remain idle before
1616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * being terminated.  If there are more than the core number of
1617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * threads currently in the pool, after waiting this amount of
1618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * time without processing a task, excess threads will be
1619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * terminated.  This overrides any value set in the constructor.
1620bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
1621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param time the time to wait.  A time value of zero will cause
1622bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        excess threads to terminate immediately after executing tasks.
1623bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param unit the time unit of the {@code time} argument
1624bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws IllegalArgumentException if {@code time} less than zero or
1625bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         if {@code time} is zero and {@code allowsCoreThreadTimeOut}
1626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #getKeepAliveTime
1627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setKeepAliveTime(long time, TimeUnit unit) {
1629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (time < 0)
1630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IllegalArgumentException();
16316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson        if (time == 0 && allowsCoreThreadTimeOut())
16326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson            throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
1633bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        long keepAliveTime = unit.toNanos(time);
1634bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        long delta = keepAliveTime - this.keepAliveTime;
1635bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        this.keepAliveTime = keepAliveTime;
1636bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        if (delta < 0)
1637bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            interruptIdleWorkers();
1638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the thread keep-alive time, which is the amount of time
1642bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * that threads in excess of the core pool size may remain
1643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * idle before being terminated.
1644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
1645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param unit the desired time unit of the result
1646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the time limit
1647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #setKeepAliveTime
1648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public long getKeepAliveTime(TimeUnit unit) {
1650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return unit.convert(keepAliveTime, TimeUnit.NANOSECONDS);
1651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1653bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /* User-level queue utilities */
1654bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
1655bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
1656bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Returns the task queue used by this executor. Access to the
1657bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * task queue is intended primarily for debugging and monitoring.
1658bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * This queue may be in active use.  Retrieving the task queue
1659bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * does not prevent queued tasks from executing.
1660bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
1661bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return the task queue
1662bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
1663bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public BlockingQueue<Runnable> getQueue() {
1664bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return workQueue;
1665bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
1666bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
1667bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
1668bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Removes this task from the executor's internal queue if it is
1669bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * present, thus causing it not to be run if it has not already
1670bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * started.
1671bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
1672bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p> This method may be useful as one part of a cancellation
1673bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * scheme.  It may fail to remove tasks that have been converted
1674bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * into other forms before being placed on the internal queue. For
1675bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * example, a task entered using {@code submit} might be
1676bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * converted into a form that maintains {@code Future} status.
1677bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * However, in such cases, method {@link #purge} may be used to
1678bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * remove those Futures that have been cancelled.
1679bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
1680bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param task the task to remove
1681bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return true if the task was removed
1682bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
1683bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public boolean remove(Runnable task) {
1684bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        boolean removed = workQueue.remove(task);
1685bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        tryTerminate(); // In case SHUTDOWN and now empty
1686bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return removed;
1687bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
1688bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
1689bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
1690bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Tries to remove from the work queue all {@link Future}
1691bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * tasks that have been cancelled. This method can be useful as a
1692bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * storage reclamation operation, that has no other impact on
1693bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * functionality. Cancelled tasks are never executed, but may
1694bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * accumulate in work queues until worker threads can actively
1695bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * remove them. Invoking this method instead tries to remove them now.
1696bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * However, this method may fail to remove tasks in
1697bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * the presence of interference by other threads.
1698bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
1699bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public void purge() {
1700bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        final BlockingQueue<Runnable> q = workQueue;
1701bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        try {
1702bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            Iterator<Runnable> it = q.iterator();
1703bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            while (it.hasNext()) {
1704bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                Runnable r = it.next();
1705bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                if (r instanceof Future<?> && ((Future<?>)r).isCancelled())
1706bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    it.remove();
1707bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            }
1708bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        } catch (ConcurrentModificationException fallThrough) {
1709bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            // Take slow path if we encounter interference during traversal.
1710bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            // Make copy for traversal and call remove for cancelled entries.
1711bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            // The slow path is more likely to be O(N*N).
1712bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            for (Object r : q.toArray())
1713bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                if (r instanceof Future<?> && ((Future<?>)r).isCancelled())
1714bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    q.remove(r);
1715bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
1716bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
1717bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        tryTerminate(); // In case SHUTDOWN and now empty
1718bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
1719bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
1720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /* Statistics */
1721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the current number of threads in the pool.
1724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
1725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the number of threads
1726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getPoolSize() {
1728bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        final ReentrantLock mainLock = this.mainLock;
1729bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        mainLock.lock();
1730bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        try {
1731bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            // Remove rare and surprising possibility of
1732bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            // isTerminated() && getPoolSize() > 0
1733bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            return runStateAtLeast(ctl.get(), TIDYING) ? 0
1734bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                : workers.size();
1735bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        } finally {
1736bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            mainLock.unlock();
1737bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
1738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the approximate number of threads that are actively
1742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * executing tasks.
1743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
1744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the number of threads
1745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getActiveCount() {
1747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final ReentrantLock mainLock = this.mainLock;
1748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        mainLock.lock();
1749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
1750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int n = 0;
1751bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            for (Worker w : workers)
1752bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                if (w.isLocked())
1753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    ++n;
1754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return n;
1755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
1756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            mainLock.unlock();
1757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the largest number of threads that have ever
1762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * simultaneously been in the pool.
1763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
1764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the number of threads
1765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getLargestPoolSize() {
1767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final ReentrantLock mainLock = this.mainLock;
1768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        mainLock.lock();
1769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
1770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return largestPoolSize;
1771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
1772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            mainLock.unlock();
1773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1777bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Returns the approximate total number of tasks that have ever been
1778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * scheduled for execution. Because the states of tasks and
1779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * threads may change dynamically during computation, the returned
1780bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * value is only an approximation.
1781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
1782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the number of tasks
1783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public long getTaskCount() {
1785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final ReentrantLock mainLock = this.mainLock;
1786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        mainLock.lock();
1787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
1788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long n = completedTaskCount;
1789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (Worker w : workers) {
1790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                n += w.completedTasks;
1791bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                if (w.isLocked())
1792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    ++n;
1793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return n + workQueue.size();
1795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
1796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            mainLock.unlock();
1797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the approximate total number of tasks that have
1802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * completed execution. Because the states of tasks and threads
1803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * may change dynamically during computation, the returned value
1804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is only an approximation, but one that does not ever decrease
1805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * across successive calls.
1806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
1807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the number of tasks
1808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public long getCompletedTaskCount() {
1810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final ReentrantLock mainLock = this.mainLock;
1811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        mainLock.lock();
1812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
1813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            long n = completedTaskCount;
1814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (Worker w : workers)
1815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                n += w.completedTasks;
1816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return n;
1817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } finally {
1818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            mainLock.unlock();
1819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18228eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    /**
18238eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * Returns a string identifying this pool, as well as its state,
18248eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * including indications of run state and estimated worker and
18258eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * task counts.
18268eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     *
18278eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     * @return a string identifying this pool, as well as its state
18288eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson     */
18298eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    public String toString() {
18308eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        long ncompleted;
18318eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        int nworkers, nactive;
18328eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        final ReentrantLock mainLock = this.mainLock;
18338eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        mainLock.lock();
18348eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        try {
18358eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            ncompleted = completedTaskCount;
18368eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            nactive = 0;
18378eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            nworkers = workers.size();
18388eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            for (Worker w : workers) {
18398eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                ncompleted += w.completedTasks;
18408eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                if (w.isLocked())
18418eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                    ++nactive;
18428eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            }
18438eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        } finally {
18448eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            mainLock.unlock();
18458eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        }
18468eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        int c = ctl.get();
18478eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        String rs = (runStateLessThan(c, SHUTDOWN) ? "Running" :
18488eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                     (runStateAtLeast(c, TERMINATED) ? "Terminated" :
18498eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                      "Shutting down"));
18508eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        return super.toString() +
18518eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            "[" + rs +
18528eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            ", pool size = " + nworkers +
18538eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            ", active threads = " + nactive +
18548eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            ", queued tasks = " + workQueue.size() +
18558eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            ", completed tasks = " + ncompleted +
18568eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            "]";
18578eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    }
18588eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson
1859bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /* Extension hooks */
1860bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
1861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Method invoked prior to executing the given Runnable in the
1863bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * given thread.  This method is invoked by thread {@code t} that
1864bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * will execute task {@code r}, and may be used to re-initialize
1865bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * ThreadLocals, or to perform logging.
1866bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
1867bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>This implementation does nothing, but may be customized in
1868bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * subclasses. Note: To properly nest multiple overridings, subclasses
1869bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * should generally invoke {@code super.beforeExecute} at the end of
1870bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * this method.
1871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
1872bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param t the thread that will run task {@code r}
1873bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param r the task that will be executed
1874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected void beforeExecute(Thread t, Runnable r) { }
1876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1878bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Method invoked upon completion of execution of the given Runnable.
1879bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * This method is invoked by the thread that executed the task. If
1880bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * non-null, the Throwable is the uncaught {@code RuntimeException}
1881bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * or {@code Error} that caused execution to terminate abruptly.
1882bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
1883bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>This implementation does nothing, but may be customized in
1884bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * subclasses. Note: To properly nest multiple overridings, subclasses
1885bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * should generally invoke {@code super.afterExecute} at the
1886bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * beginning of this method.
1887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
1888bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p><b>Note:</b> When actions are enclosed in tasks (such as
1889bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * {@link FutureTask}) either explicitly or via methods such as
1890bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * {@code submit}, these task objects catch and maintain
1891bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * computational exceptions, and so they do not cause abrupt
1892bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * termination, and the internal exceptions are <em>not</em>
1893bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * passed to this method. If you would like to trap both kinds of
1894bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * failures in this method, you can further probe for such cases,
1895bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * as in this sample subclass that prints either the direct cause
1896bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * or the underlying exception if a task has been aborted:
1897bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
1898bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *  <pre> {@code
1899bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * class ExtendedExecutor extends ThreadPoolExecutor {
1900bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *   // ...
1901bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *   protected void afterExecute(Runnable r, Throwable t) {
1902bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *     super.afterExecute(r, t);
1903bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *     if (t == null && r instanceof Future<?>) {
1904bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *       try {
1905bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         Object result = ((Future<?>) r).get();
1906bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *       } catch (CancellationException ce) {
1907bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *           t = ce;
1908bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *       } catch (ExecutionException ee) {
1909bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *           t = ee.getCause();
1910bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *       } catch (InterruptedException ie) {
1911bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *           Thread.currentThread().interrupt(); // ignore/reset
1912bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *       }
1913bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *     }
1914bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *     if (t != null)
1915bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *       System.out.println(t);
1916bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *   }
1917bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * }}</pre>
1918bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
1919bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param r the runnable that has completed
1920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param t the exception that caused termination, or null if
1921bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * execution completed normally
1922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected void afterExecute(Runnable r, Throwable t) { }
1924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Method invoked when the Executor has terminated.  Default
1927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * implementation does nothing. Note: To properly nest multiple
1928adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * overridings, subclasses should generally invoke
1929bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * {@code super.terminated} within this method.
1930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected void terminated() { }
1932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1933bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /* Predefined RejectedExecutionHandlers */
1934bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
1935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * A handler for rejected tasks that runs the rejected task
1937bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * directly in the calling thread of the {@code execute} method,
1938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * unless the executor has been shut down, in which case the task
1939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is discarded.
1940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1941bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public static class CallerRunsPolicy implements RejectedExecutionHandler {
1942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1943bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         * Creates a {@code CallerRunsPolicy}.
1944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
1945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public CallerRunsPolicy() { }
1946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1947adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1948adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Executes task r in the caller's thread, unless the executor
1949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * has been shut down, in which case the task is discarded.
1950bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         *
1951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param r the runnable task requested to be executed
1952adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param e the executor attempting to execute this task
1953adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
1954adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
1955adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!e.isShutdown()) {
1956adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                r.run();
1957adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1958adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1959adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1961adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1962adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * A handler for rejected tasks that throws a
1963bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * {@code RejectedExecutionException}.
1964adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1965adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static class AbortPolicy implements RejectedExecutionHandler {
1966adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1967bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         * Creates an {@code AbortPolicy}.
1968adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
1969adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public AbortPolicy() { }
1970adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1971adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1972adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Always throws RejectedExecutionException.
1973bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         *
1974adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param r the runnable task requested to be executed
1975adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param e the executor attempting to execute this task
1976adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @throws RejectedExecutionException always.
1977adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
1978adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
19798eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson            throw new RejectedExecutionException("Task " + r.toString() +
19808eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                                                 " rejected from " +
19818eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                                                 e.toString());
1982adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1984adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1985adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1986adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * A handler for rejected tasks that silently discards the
1987adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * rejected task.
1988adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static class DiscardPolicy implements RejectedExecutionHandler {
1990adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1991bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         * Creates a {@code DiscardPolicy}.
1992adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
1993adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public DiscardPolicy() { }
1994adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1995adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
1996adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Does nothing, which has the effect of discarding task r.
1997bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         *
1998adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param r the runnable task requested to be executed
1999adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param e the executor attempting to execute this task
2000adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
2001adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
2002adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2003adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2004adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2005adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2006adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * A handler for rejected tasks that discards the oldest unhandled
2007bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * request and then retries {@code execute}, unless the executor
2008adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is shut down, in which case the task is discarded.
2009adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2010adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static class DiscardOldestPolicy implements RejectedExecutionHandler {
2011adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
2012bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         * Creates a {@code DiscardOldestPolicy} for the given executor.
2013adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
2014adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public DiscardOldestPolicy() { }
2015adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
2016adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        /**
2017adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * Obtains and ignores the next task that the executor
2018adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * would otherwise execute, if one is immediately available,
2019adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * and then retries execution of task r, unless the executor
2020adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * is shut down, in which case task r is instead discarded.
2021bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson         *
2022adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param r the runnable task requested to be executed
2023adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         * @param e the executor attempting to execute this task
2024adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         */
2025adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
2026adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!e.isShutdown()) {
2027adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                e.getQueue().poll();
2028adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                e.execute(r);
2029adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
2030adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
2031adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
2032adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
2033