zoukankan      html  css  js  c++  java
  • ThreadPoolExecutor解析

    Executor接口的定义:http://donald-draper.iteye.com/blog/2365625 
    ExecutorService接口定义:http://donald-draper.iteye.com/blog/2365738 
    Future接口定义:http://donald-draper.iteye.com/blog/2365798 
    FutureTask解析:http://donald-draper.iteye.com/blog/2365980 
    CompletionService接口定义:http://donald-draper.iteye.com/blog/2366239 
    ExecutorCompletionService解析:http://donald-draper.iteye.com/blog/2366254 
    AbstractExecutorService解析:http://donald-draper.iteye.com/blog/2366348 
    ScheduledExecutorService接口定义:http://donald-draper.iteye.com/blog/2366436 

    Java代码  收藏代码
    1. package java.util.concurrent;  
    2. import java.util.concurrent.locks.AbstractQueuedSynchronizer;  
    3. import java.util.concurrent.locks.Condition;  
    4. import java.util.concurrent.locks.ReentrantLock;  
    5. import java.util.concurrent.atomic.AtomicInteger;  
    6. import java.util.*;  
    7.   
    8. /** 
    9.  * An {@link ExecutorService} that executes each submitted task using 
    10.  * one of possibly several pooled threads, normally configured 
    11.  * using {@link Executors} factory methods. 
    12.  * 
    13.  ThreadPoolExecutor用线程池中的线程执行提交的任务,一般通过Executors的 
    14.  工厂方法创建ThreadPoolExecutor。 
    15.  * <p>Thread pools address two different problems: they usually 
    16.  * provide improved performance when executing large numbers of 
    17.  * asynchronous tasks, due to reduced per-task invocation overhead, 
    18.  * and they provide a means of bounding and managing the resources, 
    19.  * including threads, consumed when executing a collection of tasks. 
    20.  * Each {@code ThreadPoolExecutor} also maintains some basic 
    21.  * statistics, such as the number of completed tasks. 
    22.  * 
    23.  线程池主要是解决两类不同的问题:线程用于在需要执行大量异步任务的情况下,改善性能, 
    24.  者得力于线程池减少了每个任务运行的负载,同时提供了管理执行一个任务集所用的资源,包括线程。 
    25. ThreadPoolExecutor提供了一些基本的统计,比如完成任务的数量。 
    26.  * <p>To be useful across a wide range of contexts, this class 
    27.  * provides many adjustable parameters and extensibility 
    28.  * hooks. However, programmers are urged to use the more convenient 
    29.  * {@link Executors} factory methods {@link 
    30.  * Executors#newCachedThreadPool} (unbounded thread pool, with 
    31.  * automatic thread reclamation), {@link Executors#newFixedThreadPool} 
    32.  * (fixed size thread pool) and {@link 
    33.  * Executors#newSingleThreadExecutor} (single background thread), that 
    34.  * preconfigure settings for the most common usage 
    35.  * scenarios. Otherwise, use the following guide when manually 
    36.  * configuring and tuning this class: 
    37.  * 
    38.  为了在大部分上下文或场景,保证线程池的高效性,ThreadPoolExecutor提供了一些可调整的参数 
    39.  和扩展的hooks。开发者可以用更方便的Executors的工厂方法newCachedThreadPool创建一个无界的 
    40.  原子回收线程的线程池,newFixedThreadPool方法创建一个固定大小的线程池,newSingleThreadExecutor 
    41.  创建一个单线程的后台线程,这些都是为大部分应用场景设置的默认线程池配置。 
    42.  如果以上线程方法不足以满足应用场景,可以手动配置和调校线程池ThreadPoolExecutor。 
    43.  * <dl> 
    44.  * 
    45.  * <dt>Core and maximum pool sizes</dt> 
    46.  * 
    47.  核心和最大线程池数量 
    48.  * <dd>A {@code ThreadPoolExecutor} will automatically adjust the 
    49.  * pool size (see {@link #getPoolSize})  
    50.  * according to the bounds set by 
    51.  * corePoolSize (see {@link #getCorePoolSize}) and 
    52.  * maximumPoolSize (see {@link #getMaximumPoolSize}). 
    53.  * 
    54.  线程池执行器将会根据核心线程池数量和最大线程池数量自动地调整线程池大小。 
    55.  * When a new task is submitted in method {@link #execute}, and fewer 
    56.  * than corePoolSize threads are running, a new thread is created to 
    57.  * handle the request, even if other worker threads are idle.  If 
    58.  * there are more than corePoolSize but less than maximumPoolSize 
    59.  * threads running, a new thread will be created only if the queue is 
    60.  * full.  By setting corePoolSize and maximumPoolSize the same, you 
    61.  * create a fixed-size thread pool. By setting maximumPoolSize to an 
    62.  * essentially unbounded value such as {@code Integer.MAX_VALUE}, you 
    63.  * allow the pool to accommodate an arbitrary number of concurrent 
    64.  * tasks. Most typically, core and maximum pool sizes are set only 
    65.  * upon construction, but they may also be changed dynamically using 
    66.  * {@link #setCorePoolSize} and {@link #setMaximumPoolSize}. </dd> 
    67.  * 
    68.  当一个新任务提交的线程池执行时,如果当前正在运行的线程数小于核心线程数,即使线程 
    69.  池中有空闲的线程,仍创建一个新线程处理任务执行请求,即创建一个新的任务线程执行任务。 
    70.  如果有大于核心线程池数量,小于最大线程池数量的线程在运行,一个新的任务线程将被创建, 
    71.  直到任务队列满为止。当设置corePoolSize和maximumPoolSize相等时,即创建一个 
    72.  固定大小的线程池。如果需要设置maximumPoolSize为无界的,比如Integer.MAX_VALUE, 
    73.  那么将允许线程池容纳任意数量的任务并发执行。在典型的场景中,corePoolSize和maximumPoolSize 
    74.  仅仅在构造中设置,但是我们也可以动态的调整用#setCorePoolSize和#setMaximumPoolSize函数。 
    75.  
    76.  * <dt>On-demand construction</dt> 
    77.  * 
    78.  * <dd> By default, even core threads are initially created and 
    79.  * started only when new tasks arrive, but this can be overridden 
    80.  * dynamically using method {@link #prestartCoreThread} or {@link 
    81.  * #prestartAllCoreThreads}.  You probably want to prestart threads if 
    82.  * you construct the pool with a non-empty queue. </dd> 
    83.  * 
    84.  在默认情况,只有在新任务到达时,才开始创建和启动核心线程, 
    85.  但是我们可以#prestartCoreThread和 #prestartAllCoreThreads方法动态调整 
    86.  默认核心线程调度策略。prestartCoreThread方法为创一个空闲任务线程等待任务的到达, 
    87.  prestartAllCoreThreads创建核心线程池数量的空闲任务线程等待任务的到达。 
    88.  如果我们构造是非空队列的线程池,也许我们想预启动任务线程。 
    89.  * <dt>Creating new threads</dt> 
    90.  * 
    91.  * <dd>New threads are created using a {@link ThreadFactory}.  If not 
    92.  * otherwise specified, a {@link Executors#defaultThreadFactory} is 
    93.  * used, that creates threads to all be in the same {@link 
    94.  * ThreadGroup} and with the same {@code NORM_PRIORITY} priority and 
    95.  * non-daemon status. By supplying a different ThreadFactory, you can 
    96.  * alter the thread's name, thread group, priority, daemon status, 
    97.  * etc. If a {@code ThreadFactory} fails to create a thread when asked 
    98.  * by returning null from {@code newThread}, the executor will 
    99.  * continue, but might not be able to execute any tasks. Threads 
    100.  * should possess the "modifyThread" {@code RuntimePermission}. If 
    101.  * worker threads or other threads using the pool do not possess this 
    102.  * permission, service may be degraded: configuration changes may not 
    103.  * take effect in a timely manner, and a shutdown pool may remain in a 
    104.  * state in which termination is possible but not completed.</dd> 
    105.  * 
    106.  ThreadPoolExecutor用ThreadFactory创建新的任务线程。如果线程工程没有特别的指定, 
    107.  默认线程工厂为Executors#defaultThreadFactory,默认线程工厂创建线程,具有相同的优先级NORM_PRIORITY, 
    108.  相同的线程组ThreadGroup,并且为非守护线程。我们可以提供一个不同的线程功能, 
    109.  用于改变线程名,线程分组,线程优先级,守护状态等。当线程工厂创建线程失败时, 
    110.  执行器将会,忽略任务,也许可能知道执行器不能够执行任何任务。线程应该可以控制 
    111. modifyThread运行时允许。如果工作线程或者其他线程池线程不能够控制RuntimePermission(modifyThread) 
    112. ,线程池服务将会degraded(退化,降级):配置的改变,也许不能够及时生效,一个关闭的 
    113. 线程池也许停留在结束状态,但任务为完成。 
    114.  * <dt>Keep-alive times</dt> 
    115.  * 
    116.  * <dd>If the pool currently has more than corePoolSize threads, 
    117.  * excess threads will be terminated if they have been idle for more 
    118.  * than the keepAliveTime (see {@link #getKeepAliveTime}). This 
    119.  * provides a means of reducing resource consumption when the pool is 
    120.  * not being actively used. If the pool becomes more active later, new 
    121.  * threads will be constructed. This parameter can also be changed 
    122.  * dynamically using method {@link #setKeepAliveTime}. Using a value 
    123.  * of {@code Long.MAX_VALUE} {@link TimeUnit#NANOSECONDS} effectively 
    124.  * disables idle threads from ever terminating prior to shut down. By 
    125.  * default, the keep-alive policy applies only when there are more 
    126.  * than corePoolSizeThreads. But method {@link 
    127.  * #allowCoreThreadTimeOut(boolean)} can be used to apply this 
    128.  * time-out policy to core threads as well, so long as the 
    129.  * keepAliveTime value is non-zero. </dd> 
    130. 如果当前线程池中的线程数量大于核心线程池数量,如果空闲线程空闲的时间大于 
    131. 保活时间keepAliveTime的线程,则将会被终止。当线程池没有充分利用的情况下, 
    132. 此策略可以减少资源的消耗。如果线程池之后,变得更活跃,则新的任务线程将会被闯将。 
    133. 我们可以用#setKeepAliveTime方法动态的改变保活时间,用一个 Long.MAX_VALU,TimeUnit#NANOSECONDS 
    134. 作为保活时间,那么空闲的线程可以避免在线程池关闭之前被终止。保活策略只有在当前线程池线程数量大于 
    135. 核心线程池数量时,才起作用。#allowCoreThreadTimeOut用于控制当任务线程空闲时,是否允许线程等待 
    136. keepAliveTime时间,以便在这个过程中,有新的任务进来。 
    137.  * 
    138.  * <dt>Queuing</dt> 
    139.  * 
    140.  * <dd>Any {@link BlockingQueue} may be used to transfer and hold 
    141.  * submitted tasks.  The use of this queue interacts with pool sizing: 
    142.  * 
    143.  BlockingQueu用于存放提交的任务,队列的实际容量与线程池大小相关联。 
    144.  * [list] 
    145.  * 
    146.  * <li> If fewer than corePoolSize threads are running, the Executor 
    147.  * always prefers adding a new thread 
    148.  * rather than queuing.</li> 
    149.  * 
    150.  如果当前线程池任务线程数量小于核心线程池数量,执行器总是优先创建一个任务线程, 
    151.  而不是从线程队列中取一个空闲线程。 
    152.  * <li> If corePoolSize or more threads are running, the Executor 
    153.  * always prefers queuing a request rather than adding a new 
    154.  * thread.</li> 
    155.  * 
    156. 如果当前线程池任务线程数量大于核心线程池数量,执行器总是优先从线程队列中取一个空闲线程, 
    157. 而不是创建一个任务线程。 
    158.  * <li> If a request cannot be queued, a new thread is created unless 
    159.  * this would exceed maximumPoolSize, in which case, the task will be 
    160.  * rejected.</li> 
    161.  * 
    162.  如果当前线程池任务线程数量大于核心线程池数量,且队列中无空闲任务线程,将会创建 
    163.  一个任务线程,直到超出maximumPoolSize,如果超时maximumPoolSize,则任务将会被拒绝。 
    164.  * [/list] 
    165.  * 
    166.  * There are three general strategies for queuing: 
    167.  * [list=1] 
    168.  * 
    169.  ThreadPoolExecutor有3中出队列策略 
    170.  * <li> [i] Direct handoffs.[/i] A good default choice for a work 
    171.  * queue is a {@link SynchronousQueue} that hands off tasks to threads 
    172.  * without otherwise holding them. Here, an attempt to queue a task 
    173.  * will fail if no threads are immediately available to run it, so a 
    174.  * new thread will be constructed. This policy avoids lockups when 
    175.  * handling sets of requests that might have internal dependencies. 
    176.  * Direct handoffs generally require unbounded maximumPoolSizes to 
    177.  * avoid rejection of new submitted tasks. This in turn admits the 
    178.  * possibility of unbounded thread growth when commands continue to 
    179.  * arrive on average faster than they can be processed.  </li> 
    180.  * 
    181. 直接handoffs,队列非默认选择为同步队列SynchronousQueue,SynchronousQueue是一个 
    182. take同时对应一个put,反之亦然。如果没有线程立刻可用,则任务线程尝试出队列失败, 
    183. 一个新的线程将会被创建。这种策略用于处理的任务请求对任务队列中的其他任务有依赖的 
    184. 情况,这种策略可以避免查找。Direct handoffs策略一般需要一个无界的maximumPoolSizes, 
    185. 为了避免拒绝新任务的提交。这样在任务提交数量平均速度大于线程池可以处理的速度时,可到导致 
    186. 无限的任务继续提交。 
    187.  
    188.  * <li>[i] Unbounded queues.[/i] Using an unbounded queue (for 
    189.  * example a {@link LinkedBlockingQueue} without a predefined 
    190.  * capacity) will cause new tasks to wait in the queue when all 
    191.  * corePoolSize threads are busy. Thus, no more than corePoolSize 
    192.  * threads will ever be created. (And the value of the maximumPoolSize 
    193.  * therefore doesn't have any effect.)  This may be appropriate when 
    194.  * each task is completely independent of others, so tasks cannot 
    195.  * affect each others execution; for example, in a web page server. 
    196.  * While this style of queuing can be useful in smoothing out 
    197.  * transient bursts of requests, it admits the possibility of 
    198.  * unbounded work queue growth when commands continue to arrive on 
    199.  * average faster than they can be processed.  </li> 
    200.  * 
    201. Unbounded queues无界的任务队列的默认选择为没有初始化容量的LinkedBlockingQueue, 
    202. 当所有核心任务线程处于忙碌中时,将会引起新的任务在队列中等待。 
    203. 这样没有大于核心线程池数量的线程被创建。(因此这种策略下,maximumPoolSize将会无效)。 
    204. LinkedBlockingQueue策略可以用于每个任务独立完成,任务之间的执行互不影响; 
    205. 比如Web服务器。这种策略在突然并发量增大时,平滑的处理突发的并发量的场景中, 
    206. 比较有效,同时在任务提交数量平均速度大于线程池可以处理的速度时,可到导致 
    207. 无限的任务继续提交。 
    208.  
    209.  * <li>[i]Bounded queues.[/i] A bounded queue (for example, an 
    210.  * {@link ArrayBlockingQueue}) helps prevent resource exhaustion when 
    211.  * used with finite maximumPoolSizes, but can be more difficult to 
    212.  * tune and control.  Queue sizes and maximum pool sizes may be traded 
    213.  * off for each other: Using large queues and small pools minimizes 
    214.  * CPU usage, OS resources, and context-switching overhead, but can 
    215.  * lead to artificially low throughput.  If tasks frequently block (for 
    216.  * example if they are I/O bound), a system may be able to schedule 
    217.  * time for more threads than you otherwise allow. Use of small queues 
    218.  * generally requires larger pool sizes, which keeps CPUs busier but 
    219.  * may encounter unacceptable scheduling overhead, which also 
    220.  * decreases throughput.  </li> 
    221.  * 
    222.  Bounded queues有界队列,可以选择ArrayBlockingQueue,用有限的maximumPoolSizes 
    223.  阻止资源的浪费,但实际上是很难调校和控制的。队列的size和最大线程池size也许有一个 
    224.  这种的方案:在CPU的使用率,OS资源,上下文切换负载,可用一个队列容量大一些, 
    225. maximumPoolSizes小一些,但这样可能导致吞吐量较低。如果任务频繁地阻塞(比如IO限制), 
    226. 系统可以调度比我们允许的更多的线程。用队列容量小,一般需要maximumPoolSizes大一些, 
    227. 这样可以保当CUP充分利用,但是可能遇到不可接受的调度负载,这样也会降低吞吐量。 
    228. 这一段的意思是说,当我们使用ArrayBlockingQueue的时候,我们要在队列容量和maximumPoolSizes 
    229. 去一个这种,两者谁太大或太小,都可能导致吞吐量的下降。 
    230.  * [/list] 
    231.  * 
    232.  * </dd> 
    233.  * 
    234.  * <dt>Rejected tasks</dt> 
    235.  * 
    236.  * <dd> New tasks submitted in method {@link #execute} will be 
    237.  * [i]rejected[/i] when the Executor has been shut down, and also 
    238.  * when the Executor uses finite bounds for both maximum threads and 
    239.  * work queue capacity, and is saturated.  In either case, the {@code 
    240.  * execute} method invokes the {@link 
    241.  * RejectedExecutionHandler#rejectedExecution} method of its {@link 
    242.  * RejectedExecutionHandler}.  Four predefined handler policies are 
    243.  * provided: 
    244.  * 
    245.  当执行器关闭时,或者执行器用有界的最大线程池数量和任务队列容量饱 
    246.  和时,新提交的任务将会被拒绝。在其他情况下,execute方法将调用RejectedExecutionHandler 
    247. 的rejectedExecution方法处理任务。有四种处理策略提供如下: 
    248.   
    249.  
    250.  * [list=1] 
    251.  * 
    252.  * <li> In the default {@link ThreadPoolExecutor.AbortPolicy}, the 
    253.  * handler throws a runtime {@link RejectedExecutionException} upon 
    254.  * rejection. </li> 
    255.  * 
    256.  默认情况下,ThreadPoolExecutor.AbortPolicy策略是,在拒绝任务时,抛出 
    257. RejectedExecutionException运行时异常。 
    258.  * <li> In {@link ThreadPoolExecutor.CallerRunsPolicy}, the thread 
    259.  * that invokes {@code execute} itself runs the task. This provides a 
    260.  * simple feedback control mechanism that will slow down the rate that 
    261.  * new tasks are submitted. </li> 
    262.  * 
    263.  CallerRunsPolicy:调用线程将会运行任务,及调用execute方法的线程。 
    264.  这种策略提供了一个反馈机制减慢新任务的提交速度。 
    265.  * <li> In {@link ThreadPoolExecutor.DiscardPolicy}, a task that 
    266.  * cannot be executed is simply dropped.  </li> 
    267.  * 
    268. DiscardPolicy:直接丢弃新提交的任务 
    269.  * <li>In {@link ThreadPoolExecutor.DiscardOldestPolicy}, if the 
    270.  * executor is not shut down, the task at the head of the work queue 
    271.  * is dropped, and then execution is retried (which can fail again, 
    272.  * causing this to be repeated.) </li> 
    273.  * 
    274.  DiscardOldestPolicy:如果执行器没有关闭,队列头的任务将会被丢弃,然后执行器重新 
    275.  尝试执行任务(如果失败,则重复这一过程) 
    276.  * [/list] 
    277.  * 
    278.  * It is possible to define and use other kinds of {@link 
    279.  * RejectedExecutionHandler} classes. Doing so requires some care 
    280.  * especially when policies are designed to work only under particular 
    281.  * capacity or queuing policies. </dd> 
    282.  * 
    283.  我们也可以自己定义RejectedExecutionHandler,以适应特殊的容量和队列策略场景中。 
    284.   
    285.  * <dt>Hook methods</dt> 
    286.  * 
    287.  * <dd>This class provides {@code protected} overridable {@link 
    288.  * #beforeExecute} and {@link #afterExecute} methods that are called 
    289.  * before and after execution of each task.  These can be used to 
    290.  * manipulate the execution environment; for example, reinitializing 
    291.  * ThreadLocals, gathering statistics, or adding log 
    292.  * entries. Additionally, method {@link #terminated} can be overridden 
    293.  * to perform any special processing that needs to be done once the 
    294.  * Executor has fully terminated. 
    295.  * 
    296. ThreadPoolExecutor提供了#beforeExecute和#afterExecute方法分别在任务被执行前和 
    297. 执行后调用,我们可重写这两个方法,做些需要的工作。这两个方法可以用于控制执行环境。 
    298. 比如重新初始化ThreadLocals类变量,统计,添加日志等。#terminated方法可以被重写, 
    299. 用于执行一些特殊的处理,在执行器完全结束前。 
    300.  * <p>If hook or callback methods throw exceptions, internal worker 
    301.  * threads may in turn fail and abruptly terminate.</dd> 
    302.  * 
    303.  如果hook和回调方法抛出异常,内部的任务线程将会失败并结束。 
    304.  * <dt>Queue maintenance</dt> 
    305.  * 
    306.  * <dd> Method {@link #getQueue} allows access to the work queue for 
    307.  * purposes of monitoring and debugging.  Use of this method for any 
    308.  * other purpose is strongly discouraged.  Two supplied methods, 
    309.  * {@link #remove} and {@link #purge} are available to assist in 
    310.  * storage reclamation when large numbers of queued tasks become 
    311.  * cancelled.</dd> 
    312.  * 
    313.  #getQueue可以访问任务队列,用于监控和调试。如果这个方法用于其他目的, 
    314.  强烈不建议。#remove和#purge方法用于回收空间,在大量的队列任务被取消时。 
    315.  * <dt>Finalization</dt> 
    316.  * 
    317.  * <dd> A pool that is no longer referenced in a program [i]AND[/i] 
    318.  * has no remaining threads will be {@code shutdown} automatically. If 
    319.  * you would like to ensure that unreferenced pools are reclaimed even 
    320.  * if users forget to call {@link #shutdown}, then you must arrange 
    321.  * that unused threads eventually die, by setting appropriate 
    322.  * keep-alive times, using a lower bound of zero core threads and/or 
    323.  * setting {@link #allowCoreThreadTimeOut(boolean)}.  </dd> 
    324.  * 
    325.  当一个线程池不再被引用,且线程池中没有任务线程,线程池将会自动关闭。 
    326.  如果您忘记了关闭线程池,但想保证无引用的线程池被回收,您可以通过设置 
    327. keep-alive保活时间,用一个核心线程数较小的线程池,或设置#allowCoreThreadTimeOut 
    328. 运行线程空闲时等待或不等待。 
    329.  * </dl> 
    330.  * 
    331.  * <p> <b>Extension example</b>. Most extensions of this class 
    332.  * override one or more of the protected hook methods. For example, 
    333.  * here is a subclass that adds a simple pause/resume feature: 
    334.  * 
    335.  扩展实例。大部分的扩展实例会重写一个或多个protected hook方法。 
    336.  下面一个实例添加了暂停和恢复的特点。 
    337.  *  <pre> {@code 
    338.  * class PausableThreadPoolExecutor extends ThreadPoolExecutor { 
    339.  *   private boolean isPaused; 
    340.  *   private ReentrantLock pauseLock = new ReentrantLock(); 
    341.  *   private Condition unpaused = pauseLock.newCondition(); 
    342.  * 
    343.  *   public PausableThreadPoolExecutor(...) { super(...); } 
    344.  * 
    345.  *   protected void beforeExecute(Thread t, Runnable r) { 
    346.  *     super.beforeExecute(t, r); 
    347.  *     pauseLock.lock(); 
    348.  *     try { 
    349.  *       while (isPaused) unpaused.await(); 
    350.  *     } catch (InterruptedException ie) { 
    351.  *       t.interrupt(); 
    352.  *     } finally { 
    353.  *       pauseLock.unlock(); 
    354.  *     } 
    355.  *   } 
    356.  * 
    357.  *   public void pause() { 
    358.  *     pauseLock.lock(); 
    359.  *     try { 
    360.  *       isPaused = true; 
    361.  *     } finally { 
    362.  *       pauseLock.unlock(); 
    363.  *     } 
    364.  *   } 
    365.  * 
    366.  *   public void resume() { 
    367.  *     pauseLock.lock(); 
    368.  *     try { 
    369.  *       isPaused = false; 
    370.  *       unpaused.signalAll(); 
    371.  *     } finally { 
    372.  *       pauseLock.unlock(); 
    373.  *     } 
    374.  *   } 
    375.  * }}</pre> 
    376.  * 
    377.  * @since 1.5 
    378.  * @author Doug Lea 
    379.  */  
    380. public class ThreadPoolExecutor extends AbstractExecutorService {  
    381. /** 
    382.      * The main pool control state, ctl, is an atomic integer packing 
    383.      * two conceptual fields 
    384.      *   workerCount, indicating the effective number of threads 
    385.      *   runState,    indicating whether running, shutting down etc 
    386.      * 
    387.      ctl线程的主要控制状态,包装者两个概念fields,workerCount表示有效的 
    388.      任务线程数量,runState表示是否运行和关闭。 
    389.      * In order to pack them into one int, we limit workerCount to 
    390.      * (2^29)-1 (about 500 million) threads rather than (2^31)-1 (2 
    391.      * billion) otherwise representable. If this is ever an issue in 
    392.      * the future, the variable can be changed to be an AtomicLong, 
    393.      * and the shift/mask constants below adjusted. But until the need 
    394.      * arises, this code is a bit faster and simpler using an int. 
    395.      * 
    396.      为了包装workerCount和runState为一个int,我们限制任务线程数量为 
    397.      (2^29)-1 大约500百万个线程,而不是(2^31)-1两亿个线程。如果这种策略在 
    398.      将来有问题,可以将ctl改变为AtomicLong,在调整shift/mask常量。改变为AtomicLong 
    399.      执行在需要的时候,才会做,本线程池实现类用的为简单的int。 
    400.      * The workerCount is the number of workers that have been 
    401.      * permitted to start and not permitted to stop.  The value may be 
    402.      * transiently different from the actual number of live threads, 
    403.      * for example when a ThreadFactory fails to create a thread when 
    404.      * asked, and when exiting threads are still performing 
    405.      * bookkeeping before terminating. The user-visible pool size is 
    406.      * reported as the current size of the workers set. 
    407.      * 
    408.      workerCount表示允许启动不许停止的任务线程数量,即运行中的任务线程数量。 
    409.      workerCount也许瞬态与实际的存活线程有所不同,比如当任务提交执行时,线程工厂 
    410.      创建一个线程失败,退出线程在结束之前,能在执行bookkeeping(记录)。 
    411.      用户可见的线程池数量用作当前任务线程数量。 
    412.  
    413.      * The runState provides the main lifecyle control, taking on values: 
    414.      *runState提供主要的声明周期控制,有一下值 
    415.      *   RUNNING:  Accept new tasks and process queued tasks 
    416.      *   SHUTDOWN: Don't accept new tasks, but process queued tasks 
    417.      *   STOP:     Don't accept new tasks, don't process queued tasks, 
    418.      *             and interrupt in-progress tasks 
    419.      *   TIDYING:  All tasks have terminated, workerCount is zero, 
    420.      *             the thread transitioning to state TIDYING 
    421.      *             will run the terminated() hook method 
    422.      *   TERMINATED: terminated() has completed 
    423.      * 
    424.      RUNNING:接受新的任务,处理队列任务; 
    425.      SHUTDOWN:不在接受新的任务,处理队列任务; 
    426.      STOP:不在接受新任务,不处理队列任务,中断正在执行的任务线程; 
    427.      TIDYING:所有的任务已经结束,任务线程为0,线程转换到TIDYING; 
    428.      TERMINATED:线程池已将结束,即terminated()方法执行完。 
    429.      * The numerical order among these values matters, to allow 
    430.      * ordered comparisons. The runState monotonically increases over 
    431.      * time, but need not hit each state. The transitions are: 
    432.      *几种状态的关系可以数字化的比较。runState随着线程池运行时间的变化, 
    433.      而增加,但是不必经过每一个状态。状态的转换如下: 
    434.      * RUNNING -> SHUTDOWN(调用shudown方法) 
    435.      *    On invocation of shutdown(), perhaps implicitly in finalize() 
    436.      * (RUNNING or SHUTDOWN) -> STOP(调用shutdownNow方法) 
    437.      *    On invocation of shutdownNow() 
    438.      * SHUTDOWN -> TIDYING(当任务队列和线程池都为空时) 
    439.      *    When both queue and pool are empty 
    440.      * STOP -> TIDYING(当线程池为空) 
    441.      *    When pool is empty 
    442.      * TIDYING -> TERMINATED(terminated方法执行完) 
    443.      *    When the terminated() hook method has completed 
    444.      * 
    445.      * Threads waiting in awaitTermination() will return when the 
    446.      * state reaches TERMINATED. 
    447.      * 
    448.      线程调用awaitTermination方法,将会等待线程池状态达到TERMINATED 
    449.      * Detecting the transition from SHUTDOWN to TIDYING is less 
    450.      * straightforward than you'd like because the queue may become 
    451.      * empty after non-empty and vice versa during SHUTDOWN state, but 
    452.      * we can only terminate if, after seeing that it is empty, we see 
    453.      * that workerCount is 0 (which sometimes entails a recheck -- see 
    454.      * below). 
    455.      在SHUTDOWN转换到TIDYING过程比较是难捕捉的,因为在队列在线程池非空时, 
    456.      队列可能为空,反之在SHUTDOWN状态,在看到队列为空,任务线程为0(这个有时需要进行recheck)时, 
    457.      我们可以结束线程池。 
    458.      */  
    459.     private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));  
    460.     private static final int COUNT_BITS = Integer.SIZE - 3;//任务线程数量所占的int的位数  
    461.     private static final int CAPACITY   = (1 << COUNT_BITS) - 1;//最大任务线程数量为2^29-1  
    462.   
    463.     // runState is stored in the high-order bits 运行状态runState存储在ctl的高位  
    464.     private static final int RUNNING    = -1 << COUNT_BITS;//100溢出(29)  
    465.     private static final int SHUTDOWN   =  0 << COUNT_BITS;//00(29)  
    466.     private static final int STOP       =  1 << COUNT_BITS;//01(29)  
    467.     private static final int TIDYING    =  2 << COUNT_BITS;//10(29)  
    468.     private static final int TERMINATED =  3 << COUNT_BITS;//11(29)  
    469.   
    470.     // Packing and unpacking ctl,包装和解包ctl  
    471.     private static int runStateOf(int c)     { return c & ~CAPACITY; }//运行状态  
    472.     private static int workerCountOf(int c)  { return c & CAPACITY; }//运行的任务线程数  
    473.     private static int ctlOf(int rs, int wc) { return rs | wc; }//包装运行状态和任务线程数  
    474.   
    475.     /* 
    476.      * Bit field accessors that don't require unpacking ctl. 
    477.      * These depend on the bit layout and on workerCount being never negative. 
    478.      由于任务线程计数器不会为负数,所以比较状态时,就不必要解包ctl 
    479.      */  
    480.     //是否小于某个状态  
    481.     private static boolean runStateLessThan(int c, int s) {  
    482.         return c < s;  
    483.     }  
    484.    //是否大于等于某个状态  
    485.     private static boolean runStateAtLeast(int c, int s) {  
    486.         return c >= s;  
    487.     }  
    488.    //是否是运行状态  
    489.     private static boolean isRunning(int c) {  
    490.         return c < SHUTDOWN;  
    491.     }  
    492.   
    493.     /** 
    494.      * Attempt to CAS-increment the workerCount field of ctl. 
    495.      尝试CAS任务线程数+1 
    496.      */  
    497.     private boolean compareAndIncrementWorkerCount(int expect) {  
    498.         return ctl.compareAndSet(expect, expect + 1);  
    499.     }  
    500.   
    501.     /** 
    502.      * Attempt to CAS-decrement the workerCount field of ctl. 
    503.       尝试CAS任务线程数-1 
    504.      */  
    505.     private boolean compareAndDecrementWorkerCount(int expect) {  
    506.         return ctl.compareAndSet(expect, expect - 1);  
    507.     }  
    508.   
    509.     /** 
    510.      * Decrements the workerCount field of ctl. This is called only on 
    511.      * abrupt termination of a thread (see processWorkerExit). Other 
    512.      * decrements are performed within getTask. 
    513.      在任务线程中断结束时,调用processWorkerExit方法,用于清除当前中断任务线程计数,在getTask也有用到。 
    514.      */  
    515.     private void decrementWorkerCount() {  
    516.         do {} while (! compareAndDecrementWorkerCount(ctl.get()));  
    517.     }  
    518.       
    519.     /** 
    520.      * The queue used for holding tasks and handing off to worker 
    521.      * threads.  We do not require that workQueue.poll() returning 
    522.      * null necessarily means that workQueue.isEmpty(), so rely 
    523.      * solely on isEmpty to see if the queue is empty (which we must 
    524.      * do for example when deciding whether to transition from 
    525.      * SHUTDOWN to TIDYING).  This accommodates special-purpose 
    526.      * queues such as DelayQueues for which poll() is allowed to 
    527.      * return null even if it may later return non-null when delays 
    528.      * expire. 
    529.      任务队列用于放提交到线程池的任务,并有任务线程处理。我们一般不用 
    530.     poll返回null来判断队列是否为null,而是用isEmpty方法判断队列是否为空, 
    531.     以便判断是否应该将线程池状态从SHUTDOWN切换到TIDYING。但是强烈建议在用 
    532.     DelayQueues作为任务队列时可以用poll,由于poll的方法允许返回null,即使 
    533.     在延时时间过期时,返回为非null。 
    534.      */  
    535.     private final BlockingQueue<Runnable> workQueue;  
    536.   
    537.     /** 
    538.      * Lock held on access to workers set and related bookkeeping. 
    539.      * While we could use a concurrent set of some sort, it turns out 
    540.      * to be generally preferable to use a lock. Among the reasons is 
    541.      * that this serializes interruptIdleWorkers, which avoids 
    542.      * unnecessary interrupt storms, especially during shutdown. 
    543.      * Otherwise exiting threads would concurrently interrupt those 
    544.      * that have not yet interrupted. It also simplifies some of the 
    545.      * associated statistics bookkeeping of largestPoolSize etc. We 
    546.      * also hold mainLock on shutdown and shutdownNow, for the sake of 
    547.      * ensuring workers set is stable while separately checking 
    548.      * permission to interrupt and actually interrupting. 
    549.      当需要访问任务线程集合和相关的记录需要,加锁。当我们用一个并发集合 
    550.      排序时,以便情况下,最好使用锁。其中有一个原因为interruptIdleWorkers, 
    551.      即中断空闲任务线程,这样可以在关闭线程池的过程中,避免中断风暴。 
    552.      否则退出的任务线程将会并发中断还没有中断的任务线程,即有可能发生中断风暴。 
    553.      也被用于简单的统计largestPoolSize等。在关闭和立即关闭时,我们需要持有锁, 
    554.      以便在独立检查中断允许和实际中断状态时,保证任务线程集的稳定性。 
    555.      */  
    556.     private final ReentrantLock mainLock = new ReentrantLock();  
    557.   
    558.     /** 
    559.      * Set containing all worker threads in pool. Accessed only when 
    560.      * holding mainLock. 
    561.      线程池任务线程集,当持有mainLock锁时,可以访问线程池任务线程集 
    562.      */  
    563.     private final HashSet<Worker> workers = new HashSet<Worker>();  
    564.   
    565.     /** 
    566.      * Wait condition to support awaitTermination 等待线程池结束条件 
    567.      */  
    568.     private final Condition termination = mainLock.newCondition();  
    569.   
    570.     /** 
    571.      * Tracks largest attained pool size. Accessed only under 
    572.      * mainLock. 
    573.      在持有mainLock的情况下,追踪最大线程池 
    574.      */  
    575.     private int largestPoolSize;  
    576.   
    577.     /** 
    578.      * Counter for completed tasks. Updated only on termination of 
    579.      * worker threads. Accessed only under mainLock. 
    580.       在持有mainLock的情况下,可以访问,completedTaskCount为完成任务计数器, 
    581.       在任务线程结束时,更新。 
    582.      */  
    583.     private long completedTaskCount;  
    584.   
    585.     /* 
    586.      * All user control parameters are declared as volatiles so that 
    587.      * ongoing actions are based on freshest values, but without need 
    588.      * for locking, since no internal invariants depend on them 
    589.      * changing synchronously with respect to other actions. 
    590.      所有用于控制参数被修饰为volatiles,以便正在进行的操作,都是基于最新值, 
    591.      在不需要锁的情况下,相对于其他动作,依赖于这些参数的可变量同步地改变。 
    592.      即所有需要引用这些参数的变量或动作,可以立即看到参数最新值。 
    593.      */  
    594.   
    595.     /** 
    596.      * Factory for new threads. All threads are created using this 
    597.      * factory (via method addWorker).  All callers must be prepared 
    598.      * for addWorker to fail, which may reflect a system or user's 
    599.      * policy limiting the number of threads.  Even though it is not 
    600.      * treated as an error, failure to create threads may result in 
    601.      * new tasks being rejected or existing ones remaining stuck in 
    602.      * the queue. 
    603.      * 
    604.      ThreadFactory为创建任务线程的工厂。所有任务线程的创建都是在调用addWorker 
    605.      的过程中,使用线程工厂创建。所有调用线程工厂创建任务线程的使用者,必要 
    606.      做好添加任务线程失败的心理准备,这也许会影响系统或用户的线程数量限制策略。 
    607.      即使不作为错误对待,创建任务线程失败,也许导致新任务被拒绝,或一个任务 
    608.      阻塞在任务队列中。 
    609.      * We go further and preserve pool invariants even in the face of 
    610.      * errors such as OutOfMemoryError, that might be thrown while 
    611.      * trying to create threads.  Such errors are rather common due to 
    612.      * the need to allocate a native stack in Thread#start, and users 
    613.      * will want to perform clean pool shutdown to clean up.  There 
    614.      * will likely be enough memory available for the cleanup code to 
    615.      * complete without encountering yet another OutOfMemoryError. 
    616.      即使在创建任务线程是可能会有OutOfMemoryError的错误,我们必须尽量保证 
    617.      线程池的不变性。这种事情的发生,一般是由在我们创建一个线程的本地栈时, 
    618.      用户想要关闭线程池,清除任务线程。在没有遇到OutOfMemoryError的情况下, 
    619.      将会有足够的内存用于清理工作。 
    620.  
    621.      */  
    622.     private volatile ThreadFactory threadFactory;  
    623.   
    624.     /** 
    625.      * Handler called when saturated or shutdown in execute. 
    626.      当线程池饱和或线程池关闭时,拒绝任务处理handler 
    627.      */  
    628.     private volatile RejectedExecutionHandler handler;  
    629.   
    630.     /** 
    631.      * Timeout in nanoseconds for idle threads waiting for work. 
    632.      * Threads use this timeout when there are more than corePoolSize 
    633.      * present or if allowCoreThreadTimeOut. Otherwise they wait 
    634.      * forever for new work. 
    635.      线程池空闲任务线程,等待任务的时间。如果当前线程数量大于核心线程池数量, 
    636.      且allowCoreThreadTimeOut为true,任务线程空闲,允许等待keepAliveTime时间, 
    637.      以便在这个时间范围内,有任务需要执行 
    638.      */  
    639.     private volatile long keepAliveTime;  
    640.   
    641.     /** 
    642.      * If false (default), core threads stay alive even when idle. 
    643.      * If true, core threads use keepAliveTime to time out waiting 
    644.      * for work. 
    645.      在当前线程数量大于核心线程池数量的情况下,是否允许空闲任务线程等, 
    646.      保活keepAliveTime时间,等待任务的到来。 
    647.      */  
    648.     private volatile boolean allowCoreThreadTimeOut;  
    649.   
    650.     /** 
    651.      * Core pool size is the minimum number of workers to keep alive 
    652.      * (and not allow to time out etc) unless allowCoreThreadTimeOut 
    653.      * is set, in which case the minimum is zero. 
    654.      在不允许空闲等待的情况,核心线程池数量,即保活的任务线程最小数量。 
    655.      如果允许空闲等待,线程池任务线程可能为0。 
    656.      */  
    657.     private volatile int corePoolSize;  
    658.   
    659.     /** 
    660.      * Maximum pool size. Note that the actual maximum is internally 
    661.      * bounded by CAPACITY. 
    662.      最大线程池数量,如果容量是有界的,实际为CAPACITY 
    663.      */  
    664.     private volatile int maximumPoolSize;  
    665.   
    666.     /** 
    667.      * The default rejected execution handler,默认的拒绝任务策略,抛出运行时异常 
    668.      */  
    669.     private static final RejectedExecutionHandler defaultHandler =  
    670.         new AbortPolicy();  
    671.   
    672.     /** 
    673.      * Permission required for callers of shutdown and shutdownNow. 
    674.      * We additionally require (see checkShutdownAccess) that callers 
    675.      * have permission to actually interrupt threads in the worker set 
    676.      * (as governed by Thread.interrupt, which relies on 
    677.      * ThreadGroup.checkAccess, which in turn relies on 
    678.      * SecurityManager.checkAccess). Shutdowns are attempted only if 
    679.      * these checks pass. 
    680.      当调用者调用shutdown和shutdownNow方法时,需要shutdownPerm运行时允许权限, 
    681.      以便调用者可以权限中断任务线程,在关闭的时候,首先检查调用者是否有 
    682.      shutdownPerm运行时权限。通过ThreadGroup.checkAccess是否拥有权限。 
    683.      * 
    684.      * All actual invocations of Thread.interrupt (see 
    685.      * interruptIdleWorkers and interruptWorkers) ignore 
    686.      * SecurityExceptions, meaning that the attempted interrupts 
    687.      * silently fail. In the case of shutdown, they should not fail 
    688.      * unless the SecurityManager has inconsistent policies, sometimes 
    689.      * allowing access to a thread and sometimes not. In such cases, 
    690.      * failure to actually interrupt threads may disable or delay full 
    691.      * termination. Other uses of interruptIdleWorkers are advisory, 
    692.      * and failure to actually interrupt will merely delay response to 
    693.      * configuration changes so is not handled exceptionally. 
    694.      实际上调用线程中断(interruptIdleWorkers和interruptWorkers) 
    695.      忽略SecurityExceptions,意味着尝试中断默认失败。在线程关闭的时候, 
    696.      除非SecurityManager有不一致的策略(有事允许,有时不允许),否则中断不应该失败。 
    697.      如果SecurityManager为不一致的策略,线程的中断实际上有可能失败。 
    698.      */  
    699.     private static final RuntimePermission shutdownPerm =  
    700.         new RuntimePermission("modifyThread");  
    701. }  


    自此我们把线程池ThreadPoolExecutor的java doc使用说明和变量的定义已经看完。 
    总结: 
       ThreadPoolExecutor的变量主要有核心线程池数量corePoolSize和最大线程池数量maximumPoolSize,即在当前任务线程数大于核心线程数量时,是否(allowCoreThreadTimeOut)允许空闲任务线程等,保活keepAliveTime时间,等待新任务的到来。一个线程工厂ThreadFactory用于创建任务线程,一个拒绝任务处理器RejectedExecutionHandler,默认的拒绝任务策略为AbortPolicy,抛出运行时异常,当然还有直接丢弃策略DiscardPolicy,丢弃旧的任务DiscardOldestPolicy,还有调用者执行任务策略CallerRunsPolicy。上面的变量为volatile,以便线程池执行操作时,可以使用最新的变量。 
        一个阻塞的任务队列final BlockingQueue<Runnable> workQueue,阻塞队列可以为Linked,Array,Delay,SynchronousQueue等阻塞类型,具体可以根据场景选择。默认为LinkedBlockingQueue队列,一般判断队列是否为空,用isEmpty方法,LinkedBlockingQueue一般用于任务相互之间独立,没有交叉,可独立执行。如果用SynchronousQueue,则可用poll方法判断,同步队列一般用于任务之间有依赖的关系的场景,一个任务执行依赖于另一个任务的结果。DelayQueue队列用于定时任务。ArrayBlockingQueue队列一般可以用于 
    资源有限情况,可以避免资源被耗尽。一个AtomicInteger的ctl用于包装线程状态runState和任务线程数workerCount;低29位保存任务线程数,高两位用于存储线程池状态,线程池状态已用有四种RUNNING,SHUTDOWN ,STOP,TIDYING ,TERMINATED。 
    RUNNING:接受新的任务,处理队列任务; 
    SHUTDOWN:不在接受新的任务,处理队列任务; 
    STOP:不在接受新任务,不处理队列任务,中断正在执行的任务线程; 
    TIDYING:所有的任务已经结束,任务线程为0,线程转换到TIDYING; 
    TERMINATED:线程池已结束,即terminated()方法执行完。 
    线程的状态是可以数字化比较的。 

        一个任务线程集final HashSet<Worker> workers,largestPoolSize记录线程池的最大任务线程数,completedTaskCount为完成任务计数器,在任务线程结束时,更新。一个可重入锁mainLock,用于保护非线程安全的变量如workers,largestPoolSize,completedTaskCount。 
    一个等待线程池结束条件termination,用于控制超时等待线程池关闭。 


    ThreadPoolExecutor解析二(线程工厂、工作线程,拒绝策略等):http://donald-draper.iteye.com/blog/2367064

  • 相关阅读:
    题目1.A乘以B
    题目1.A乘以B
    秋季学习总结
    题目1.A乘以B
    第一周作业
    C语言I博客作业02
    Silverlight中图像的变换(1)
    SQL SERVER 2005安装过程中COM+错误解决!
    c++ 对文件的操作
    JS标准DES加解密
  • 原文地址:https://www.cnblogs.com/miracle77hp/p/10193868.html
Copyright © 2011-2022 走看看