ThreadPoolExecutor 注释

ThreadPoolExecutor ---》AbstractExecutorService-->ExecutorService-->Executor


/**
//使用池化的线程
 * An {@link ExecutorService} that executes each submitted task using
 * one of possibly several pooled threads, normally configured
 * using {@link Executors} factory methods.
 *

//执行器-->线程池执行器
 * <p>Thread pools address two different problems: 
 //在大量异步任务执行过程中,由于减少了每个任务的调用开销
 they usually provide improved performance when executing large numbers of
 * asynchronous tasks, due to reduced per-task invocation overhead,

//提供了限制和管理资源的方法
 * and they provide a means of bounding and managing the resources,
 * including threads, consumed when executing a collection of tasks.

//一些基础统计,已完成的任务数量
 * Each {@code ThreadPoolExecutor} also maintains some basic
 * statistics, such as the number of completed tasks.
 *

//在各种情况下都很有用
 * <p>To be useful across a wide range of contexts, this class
 * provides many adjustable parameters and extensibility
 * hooks. 

//程序员要求使用方便的工厂方法
 However, 
 programmers are urged to use the more convenient
 * {@link Executors} factory methods {@link

 //1)无限数量线程池 (能自动螺旋回收)
 * Executors#newCachedThreadPool}
  (unbounded thread pool, with automatic thread reclamation), 

//固定数量线程池 (固定数量)
 {@link Executors#newFixedThreadPool}
 * (fixed size thread pool) and


//一个线程的线程池  (固定数量)
  {@link
 * Executors#newSingleThreadExecutor}
(single background thread), that  preconfigure settings for the most common usage scenarios. 


-----------------------------------------------------------------------
//手动配置
 Otherwise, use the following guide when manually configuring and tuning this class:
 *
 * <dl>
 ------------------------------
//1)核心和最大线程池数量
 * <dt>Core and maximum pool sizes</dt>
 *
 * <dd>A {@code ThreadPoolExecutor} will automatically adjust the
 * pool size (see {@link #getPoolSize})
 * according to the bounds set by
 * corePoolSize (see {@link #getCorePoolSize}) and
 * maximumPoolSize (see {@link #getMaximumPoolSize}).

//当一个新的任务提交到execute方法时,
//1--运行的线程数小于corePoolSize核心线程数,新的线程会被创建
 * When a new task is submitted in method {@link #execute(Runnable)},
 * and fewer than corePoolSize threads are running, a new thread is
 * created to handle the request, even if other worker threads are
 * idle. 

//2--当大于核心,小于max的时候,queue队列也满了,会创建新线程,
  If there are more than corePoolSize but less than
 * maximumPoolSize threads running, a new thread will be created only
 * if the queue is full. 

//corePoolSize==maximumPoolSize,,固定大小的线程池
  By setting corePoolSize and maximumPoolSize
 * the same, you create a fixed-size thread pool. 

//
 By setting maximumPoolSize to an essentially unbounded value such as {@code
 * Integer.MAX_VALUE}, you allow the pool to accommodate an arbitrary
 * number of concurrent tasks. 

 //一般来说,core and maximum pool sizes 通过构造设置,但也可以用set方法
 Most typically, core and maximum pool sizes are set only upon construction, but they may also be changed  dynamically using {@link #setCorePoolSize} and {@link#setMaximumPoolSize}. </dd>
 *

 //按需建设
 * <dt>On-demand construction</dt>
//即使是核心线程数,也是在新任务到达的时候创建
 * <dd>By default, even core threads are initially created and
 * started only when new tasks arrive, 

//预先开启核心线程数 prestartCoreThread  (1个)或者 prestartAllCoreThreads(全部)
 but this can be overridden dynamically using method {@link #prestartCoreThread} or {@link
 * #prestartAllCoreThreads}.  You probably want to prestart threads if
 * you construct the pool with a non-empty queue. </dd>


------------------------------
//2)创建新线程
 * <dt>Creating new threads</dt>

//使用 ThreadFactory 创建新线程
 * <dd>New threads are created using a {@link ThreadFactory}.  
 //如果没有特别指定,使用Executors#defaultThreadFactory创建线程
 //1-相同的ThreadGroup线程组
 //2-相同的优先级 NORM_PRIORITY
 //3-非守护进程  non-daemon
 If not otherwise specified, a {@link Executors#defaultThreadFactory} is
 * used, that creates threads to all be in the same {@link
 * ThreadGroup} and with the same {@code NORM_PRIORITY} priority and
 * non-daemon status.

//通过提供不同的线程工厂,可以修改 thread's name, thread group, priority, daemon status)等信息
  By supplying a different ThreadFactory, you can
 * alter the thread's name, thread group, priority, daemon status,
 * etc. 

//如果线程工厂创建线程失败时(newThread),执行器会继续,但是不能执行任务
 If a {@code ThreadFactory} fails to create a thread when asked
 * by returning null from {@code newThread}, the executor will
 * continue, but might not be able to execute any tasks. 

//线程需要有运行时动态修改线程的权限
 Threads  should possess the "modifyThread" {@code RuntimePermission}. If
 * worker threads or other threads using the pool do not possess this
 * permission, service may be degraded: configuration changes may not
 * take effect in a timely manner, and a shutdown pool may remain in a
 * state in which termination is possible but not completed.</dd>
 *

------------------------------
//3)线程存活时间
 * <dt>Keep-alive times</dt>
 
 //多余核心线程数的线程,会被终止
 * <dd>If the pool currently has more than corePoolSize threads,
 * excess threads will be terminated 

//空闲超过keepAliveTime 时间后
 if they have been idle for more
 * than the keepAliveTime (see {@link #getKeepAliveTime(TimeUnit)}).

 //当线程池使用不频繁的时候,提供了方法来减低资源消耗
 //当线程池又变得活跃之后,新的线程又会被创建
 * This provides a means of reducing resource consumption when the
 * pool is not being actively used. If the pool becomes more active
 * later, new threads will be constructed. 

//这个参数可以动态调整setKeepAliveTime
 This parameter can also be changed dynamically using method {@link #setKeepAliveTime(long, TimeUnit)}.  
//使用Long的最大值,纳秒可以
 Using a value of {@code Long.MAX_VALUE} {@link
 * TimeUnit#NANOSECONDS} effectively disables idle threads from ever
 * terminating prior to shut down.

//默认keep-alive 策略,只对超过核心线程数的线程有效果
  By default, the keep-alive policy
 * applies only when there are more than corePoolSize threads. 

//但是,allowCoreThreadTimeOut 这个方法可以调整,对核心线程数楪祈效果,只要keepAliveTime非0
 But method {@link #allowCoreThreadTimeOut(boolean)} can be used to
 * apply this time-out policy to core threads as well, so long as the
 * keepAliveTime value is non-zero. </dd>

------------------------------
//4)队列
 * <dt>Queuing</dt>
 
 //任意的阻塞队列BlockingQueue ,可能被使用来传递和保存提交的任务
 * <dd>Any {@link BlockingQueue} may be used to transfer and hold
 * submitted tasks.  
//使用这个队列和池的大小互相影响
 The use of this queue interacts with pool sizing:
 *


 * <ul>
// 1.正在运行线程小于核心线程数,执行器总更喜欢创建新的线程
 * <li> If fewer than corePoolSize threads are running, the Executor
 * always prefers adding a new thread
 * rather than queuing.</li>

// 2.如果核心线程数或者更多线程在运行,执行器更喜欢将任务入队,而不是创建新线程
 * <li> If corePoolSize or more threads are running, the Executor
 * always prefers queuing a request rather than adding a new
 * thread.</li>

 //3.如果任务无法入队,只要不超过最大线程数,就会创建新线程处理
 //否则,任务会被拒绝
 * <li> If a request cannot be queued, a new thread is created unless
 * this would exceed maximumPoolSize, in which case, the task will be
 * rejected.</li>
 *
 * </ul>
 *

//3种入队策略
 * There are three general strategies for queuing:
 * <ol>
 
 //1.直接传递 
 * <li> <em> Direct handoffs.</em> 
//一个好的,默认选择是同步队列 SynchronousQueue,直接给线程而不是用队列保存
 A good default choice for a work
 * queue is a {@link SynchronousQueue} that hands off tasks to threads
 * without otherwise holding them. 

//在这里,如果没有立即可用的线程,尝试将任务入队会失败。所以新的线程会被创建
 Here, an attempt to queue a task
 * will fail if no threads are immediately available to run it, so a
 * new thread will be constructed. 
 
//这种策略,避免了可能存在内部依赖的请求集
 This policy avoids lockups when
 * handling sets of requests that might have internal dependencies.
 
 //直接处理,通常需要无界的maximumPoolSizes,避免因为没有可用线程导致拒绝
 * Direct handoffs generally require unbounded maximumPoolSizes to
 * avoid rejection of new submitted tasks. 
//这反过来也促成了可能线程的无线增长(新任务生成速度快于旧任务处理)
 This in turn admits the
 * possibility of unbounded thread growth when commands continue to
 * arrive on average faster than they can be processed.  </li>

//2.无界队列 
 * <li><em> Unbounded queues.</em>
//使用无界阻塞队列LinkedBlockingQueue,导致所有的新任务等待在队列中,当所有核心线程都busy的时候
  Using an unbounded queue (for
 * example a {@link LinkedBlockingQueue} without a predefined
 * capacity) will cause new tasks to wait in the queue when all
 * corePoolSize threads are busy. 

//因此,不会与超过corePoolSize的线程被创建
 Thus, no more than corePoolSize  threads will ever be created.
  (And the value of the maximumPoolSize therefore doesn't have any effect.)  

//这里,所有的任务都是独立的。所有的任务不能相互影响
This may be appropriate when each task is completely independent of others,
 so tasks cannot affect each others execution; 

//例如,网页服务,这种类型的队列,可以处理短暂的请求爆发
 for example, in a web page server.
 * While this style of queuing can be useful in smoothing out
 * transient bursts of requests, 

//这可能导致无界阻塞队列的增长
 it admits the possibility of
 * unbounded work queue growth when commands continue to arrive on
 * average faster than they can be processed.  </li>

//3.有界队列
 * <li><em>Bounded queues.</em>

//一个有界队列,可以防止资源被耗尽
  A bounded queue (for example, an {@link ArrayBlockingQueue})
   helps prevent resource exhaustion when used with finite maximumPoolSizes, but can be more difficult to tune and control.  

 //队列大小和最大线程数将会相互影响
 Queue sizes and maximum pool sizes may be traded off for each other: 
 //大队列,小池
 1)Using large queues and small pools 
 minimizes CPU usage, OS resources, and context-switching overhead, 
 but can  lead to artificially low throughput. 
 If tasks frequently block (for example if they are I/O bound), a system may be able to schedule time for more threads than you otherwise allow. 

//小队列,大池
 2)Use of small queues generally requires larger pool sizes, 
 which keeps CPUs busier but may encounter unacceptable scheduling overhead,
 which also decreases throughput.
  </li>
 * </ol>
 *
 * </dd>

------------------------------
//5)拒绝的任务
 * <dt>Rejected tasks</dt>
//一个新的任务被提交进 #execute(Runnable) 方法时,可能会被拒绝
 * <dd>New tasks submitted in method {@link #execute(Runnable)} will be <em>rejected</em> 
 //当执行器被关闭或者最大线程数和任务队列有容量且饱和的时候
 when the Executor has been shut down, 
 and also whenthe Executor uses finite bounds for both maximum threads and work queue capacity,  and is saturated. 
//拒绝执行处理器的方法会被调用
  In either case, the {@code execute} method invokes the {@link
 * RejectedExecutionHandler#rejectedExecution(Runnable, ThreadPoolExecutor)}
 * method of its {@link RejectedExecutionHandler}.  

//4种预定义的处理策略提供如下
 Four predefined handler policies are provided:
 *
 * <ol>
 //1.中止策略,抛出RejectedExecutionException
 * <li> In the default {@link ThreadPoolExecutor.AbortPolicy}, the
 * handler throws a runtime {@link RejectedExecutionException} upon
 * rejection. </li>
 
 //2.调用者运行策略,可能降低任务提交的速率
 * <li> In {@link ThreadPoolExecutor.CallerRunsPolicy}, the thread
 * that invokes {@code execute} itself runs the task. This provides a
 * simple feedback control mechanism that will slow down the rate that
 * new tasks are submitted. </li>
 
 //3.抛弃策略,简单丢弃
 * <li> In {@link ThreadPoolExecutor.DiscardPolicy}, a task that
 * cannot be executed is simply dropped.  </li>
 
 //4.丢弃最老策略 ,丢弃任务队列中最前面的任务,如果失败,重复这个步骤
 * <li>In {@link ThreadPoolExecutor.DiscardOldestPolicy}, if the
 * executor is not shut down, the task at the head of the work queue
 * is dropped, and then execution is retried (which can fail again,
 * causing this to be repeated.) </li>
 *
 * </ol>
 *
 * It is possible to define and use other kinds of {@link
 * RejectedExecutionHandler} classes. Doing so requires some care
 * especially when policies are designed to work only under particular
 * capacity or queuing policies. </dd>

//6)关闭钩子方法
 * <dt>Hook methods</dt>
//每个任务执行的前后,执行这些钩子方法 beforeExecute + afterExecute
 * <dd>This class provides {@code protected} overridable
 * {@link #beforeExecute(Thread, Runnable)} and
 * {@link #afterExecute(Runnable, Throwable)} methods that are called
 * before and after execution of each task.  
//可以操作执行环境
 These can be used tomanipulate the execution environment; 
//如,重新初始化线程本地变量,统计,添加日志记录
 for example, reinitializing ThreadLocals, gathering statistics, or adding log entries.

//另外,方法terminated可执行任何操作,当执行器被完全关闭的时候
Additionally, method {@link #terminated} can be overridden to perform
 * any special processing that needs to be done once the Executor has
 * fully terminated.
//如果钩子或者回调方法抛出异常,则内部工作线程会失败或者童然终止
 * <p>If hook or callback methods throw exceptions, internal worker
 * threads may in turn fail and abruptly terminate.</dd>


//队列维护
 * <dt>Queue maintenance</dt>
//使用getQueue方法,访问工作队列,进行监控和调试
 * <dd>Method {@link #getQueue()} allows access to the work queue
 * for purposes of monitoring and debugging.  Use of this method for
 * any other purpose is strongly discouraged.  
//两个方法,协助仓库回收
 Two supplied methods,
 * {@link #remove(Runnable)} and {@link #purge} are available to
 * assist in storage reclamation when large numbers of queued tasks
 * become cancelled.</dd>
 *

 //终止,结束
 * <dt>Finalization</dt>
//用户没有主动调用shutdown的时候
 * <dd>A pool that is no longer referenced in a program <em>AND</em>
 * has no remaining threads will be {@code shutdown} automatically. If
 * you would like to ensure that unreferenced pools are reclaimed even
 * if users forget to call {@link #shutdown}, then you must arrange
 * that unused threads eventually die, 
 //自动回收线程池
 by setting appropriate* keep-alive times,
 using a lower bound of zero core threads 
 and/or setting {@link #allowCoreThreadTimeOut(boolean)}.  </dd>
 *
 * </dl>


//扩展案例
 * <p><b>Extension example</b>. 
//大部分扩展案例,都是重新钩子方法
 Most extensions of this class
 * override one or more of the protected hook methods. For example,
 * here is a subclass that adds a simple pause/resume feature:
 *
 *  <pre> {@code
 * class PausableThreadPoolExecutor extends ThreadPoolExecutor {
 *   private boolean isPaused;
 *   private ReentrantLock pauseLock = new ReentrantLock();
 *   private Condition unpaused = pauseLock.newCondition();
 *
 *   public PausableThreadPoolExecutor(...) { super(...); }
 *
 *   protected void beforeExecute(Thread t, Runnable r) {
 *     super.beforeExecute(t, r);
 *     pauseLock.lock();
 *     try {
 *       while (isPaused) unpaused.await();
 *     } catch (InterruptedException ie) {
 *       t.interrupt();
 *     } finally {
 *       pauseLock.unlock();
 *     }
 *   }
 *
 *   public void pause() {
 *     pauseLock.lock();
 *     try {
 *       isPaused = true;
 *     } finally {
 *       pauseLock.unlock();
 *     }
 *   }
 *
 *   public void resume() {
 *     pauseLock.lock();
 *     try {
 *       isPaused = false;
 *       unpaused.signalAll();
 *     } finally {
 *       pauseLock.unlock();
 *     }
 *   }
 * }}</pre>
 *
 * @since 1.5
 * @author Doug Lea
 */

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值