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