package java.util.concurrent;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.*;
/**
* 一个 ExecutorService,它使用可能的几个池线程之一执行每个提交的任务,通常使用 Executors 工厂方法配置。
* 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.
* 每个 ThreadPoolExecutor 还维护着一些基本的统计数据,如完成的任务数。
* Each {@code ThreadPoolExecutor} also maintains some basic
* statistics, such as the number of completed tasks.
*
* 为了便于跨大量上下文使用,此类提供了很多可调整的参数和扩展钩子 (hook)。
* <p>To be useful across a wide range of contexts, this class
* provides many adjustable parameters and extensibility
* 但是,强烈建议程序员使用较为方便的 Executors 工厂方法 Executors.newCachedThreadPool()
* (无界线程池,可以进行自动线程回收)、Executors.newFixedThreadPool(int)(固定大小线程池)
* 和 Executors.newSingleThreadExecutor()(单个后台线程),它们均为大多数使用场景预定义了设置。
* hooks. However, programmers are urged to use the more convenient
* {@link Executors} factory methods {@link
* 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>
*
* 核心和最大池大小
* <dt>Core and maximum pool sizes</dt>
*
* ThreadPoolExecutor 将根据 corePoolSize(参见 getCorePoolSize())和 maximumPoolSize
* (参见 getMaximumPoolSize())设置的边界自动调整池大小。
* <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(java.lang.Runnable) 中提交时,如果运行的线程少于
* 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
* 如果运行的线程多于 corePoolSize 而少于 maximumPoolSize,则仅当队列满时才创建新线程。
* idle. If there are more than corePoolSize but less than
* maximumPoolSize threads running, a new thread will be created only
* 如果设置的 corePoolSize 和 maximumPoolSize 相同,则创建了固定大小的线程池。
* if the queue is full. By setting corePoolSize and maximumPoolSize
* the same, you create a fixed-size thread pool. By setting
* 如果将 maximumPoolSize 设置为基本的无界值(如 Integer.MAX_VALUE),
* 则允许池容纳任意数量的并发任务。
* maximumPoolSize to an essentially unbounded value such as {@code
* Integer.MAX_VALUE}, you allow the pool to accommodate an arbitrary
* number of concurrent tasks.
* 在大多数情况下,核心和最大池大小仅基于构造来设置,不过也可以使用 setCorePoolSize(int)
* 和 setMaximumPoolSize(int) 进行动态更改。
* 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, 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>
*
* 创建一个新的线程
* <dt>Creating new threads</dt>
*
* <dd>New threads are created using a {@link ThreadFactory}. 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. By supplying a different ThreadFactory, you can
* alter the thread's name, thread group, priority, daemon status,
* 如果从 newThread 返回 null 时 ThreadFactory 未能创建线程,则executor将继续运行,
* 但不能执行任何任务。
* etc. 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
* 线程应该拥有“modifyThread”{@code RuntimePermission}。
* 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>
*
* 保持活动时间
* <dt>Keep-alive times</dt>
*
* 如果池中当前有多于 corePoolSize 的线程,则这些多出的线程在空闲时间超过 keepAliveTime 时将会终止
* <dd>If the pool currently has more than corePoolSize threads,
* excess threads will be terminated 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. This parameter can also be
* changed dynamically using method {@link #setKeepAliveTime(long,
* TimeUnit)}.
* 使用一个值{@code Long。MAX_VALUE} {@link TimeUnit#NANOSECONDS}有效地禁止空闲线程在关闭之前终止。
* Using a value of {@code Long.MAX_VALUE} {@link
* TimeUnit#NANOSECONDS} effectively disables idle threads from ever
* terminating prior to shut down.
* 默认情况下,保持活动策略只在有多于 corePoolSizeThreads 的线程时应用。但是只要 keepAliveTime 值非 0,
* allowCoreThreadTimeOut(boolean) 方法也可将此超时策略应用于核心线程。
* By default, the keep-alive policy
* applies only when there are more than corePoolSize threads. 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>
*
* <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>
*
* <li> If fewer than corePoolSize threads are running, the Executor
* always prefers adding a new thread
* rather than queuing.</li>
*
* <li> If corePoolSize or more threads are running, the Executor
* always prefers queuing a request rather than adding a new
* thread.</li>
*
* <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>
*
* 入队有三种通用策略:
* There are three general strategies for queuing:
* <ol>
* 1、直接提交。 工作队列的一个好的默认选项是 SynchronousQueue,它将任务直接提交给线程而不保持它们。
* <li> <em> Direct handoffs.</em> 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> 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。(因此,maximumPoolSize 的值也就无效了。)
* 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、有界队列。当使用有限的 maximumPoolSizes 时,有界队列(如 ArrayBlockingQueue)
* 有助于防止资源耗尽,但是可能较难调整和控制。
* <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.
* 队列大小和最大池大小可能需要相互折衷:使用大型队列和小型池可以最大限度地降低 CPU 使用率、
* 操作系统资源和上下文切换开销,但是会导致人为的低吞吐量。
* Queue sizes and maximum pool sizes may be traded
* off for each other: Using large queues and small pools minimizes
* CPU usage, OS resources, and context-switching overhead, but can
* lead to artificially low throughput.
* 如果任务经常阻塞(例如,它们受到I/O的限制),系统可能会为更多的线程安排时间。
* 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. Use of small queues
* 使用小型队列通常要求较大的池大小,CPU 使用率较高,但是可能遇到不可接受的调度开销,这样也会降低吞吐量。
* generally requires larger pool sizes, which keeps CPUs busier but
* may encounter unacceptable scheduling overhead, which also
* decreases throughput. </li>
*
* </ol>
*
* </dd>
* 拒绝任务
* <dt>Rejected tasks</dt>
*
* <dd>New tasks submitted in method {@link #execute(Runnable)} will be
* <em>rejected</em> when the Executor has been shut down, and also when
* the 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}.
* 下面提供了四种预定义的处理程序策略:
* Four predefined handler policies are provided:
*
* <ol>
*
* 在默认的 ThreadPoolExecutor.AbortPolicy 中,处理程序遭到拒绝将抛出运行时 RejectedExecutionException。
* <li> In the default {@link ThreadPoolExecutor.AbortPolicy}, the
* handler throws a runtime {@link RejectedExecutionException} upon
* rejection. </li>
*
* <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>
*
* 在 ThreadPoolExecutor.DiscardPolicy 中,不能执行的任务将被删除。
* <li> In {@link ThreadPoolExecutor.DiscardPolicy}, a task that
* cannot be executed is simply dropped. </li>
*
* 在 ThreadPoolExecutor.DiscardOldestPolicy 中,如果执行程序尚未关闭,
* 则位于工作队列头部的任务将被删除,然后重试执行程序(如果再次失败,则重复此过程)。
* <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>
*
* 定义和使用其他种类的 RejectedExecutionHandler 类也是可能的,但这样做需要非常小心,
* 尤其是当策略仅用于特定容量或排队策略时。
* 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>
*
* 钩子 (hook) 方法
* <dt>Hook methods</dt>
*
* <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 to
* manipulate the execution environment; for example, reinitializing
* ThreadLocals, gathering statistics, or adding log entries.
* 此外,还可以重写方法 terminated() 来执行 Executor 完全终止后需要完成的所有特殊处理。
* Additionally, method {@link #terminated} can be overridden to perform
* any special processing that needs to be done once the Executor has
* fully terminated.
*
* 如果钩子 (hook) 或回调方法抛出异常,则内部工作线程将依次失败并突然终止。
* <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)}和{@link #purge}可用于在大量排队任务被取消时帮助回收存储。
* {@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>
*
* 程序不再引用的池 AND 没有剩余线程会自动 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
*/
public class ThreadPoolExecutor extends AbstractExecutorService {
/**
* 主池控制状态ctl是一个原子整数,包含两个概念字段
* The main pool control state, ctl, is an atomic integer packing
* two conceptual fields
* workerCount, indicating the effective number of threads 指示有效线程数
* runState, indicating whether running, shutting down etc 指示是否运行、关闭等
*
* 为了将它们打包成一个int型,我们将workerCount限制为(2^29)-1(大约5亿)个线程,而不是(2^31)-1(20亿)个线程。
* In order to pack them into one int, we limit workerCount to
* (2^29)-1 (about 500 million) threads rather than (2^31)-1 (2
* billion) otherwise representable.
* 如果将来出现这个问题,可以将变量更改为一个AtomicLong,并调整下面的shift/mask常量。
* If this is ever an issue in
* the future, the variable can be changed to be an AtomicLong,
* and the shift/mask constants below adjusted. But until the need
* 但是在需要之前,使用int可以使这段代码更快、更简单一点。
* arises, this code is a bit faster and simpler using an int.
*
* The workerCount is the number of workers that have been
* permitted to start and not permitted to stop.
* 这个值可能与实际的活动线程数有短暂的不同,例如当ThreadFactory在被请求时没有创建线程,
* 或者在退出的线程在终止之前仍在执行记帐时。
* The value may be
* transiently different from the actual number of live threads,
* for example when a ThreadFactory fails to create a thread when
* asked, and when exiting threads are still performing
* bookkeeping before terminating. The user-visible pool size is
* 用户可见的池大小报告为工作集的当前大小。
* reported as the current size of the workers set.
*
* The runState provides the main lifecycle control, taking on values:
*
* 接受新任务并处理排队的任务
* RUNNING: Accept new tasks and process queued tasks
*
* 不接受新任务,但处理排队的任务
* SHUTDOWN: Don't accept new tasks, but process queued tasks
*
* 不要接受新任务,不要处理排队的任务,不要中断正在进行的任务
* STOP: Don't accept new tasks, don't process queued tasks,
* and interrupt in-progress tasks
*
* 所有的任务都已终止,workerCount为0,状态TIDYING的线程将运行terminate()钩子方法
* TIDYING: All tasks have terminated, workerCount is zero,
* the thread transitioning to state TIDYING
* will run the terminated() hook method
*
* terminated()方法已经完成
* TERMINATED: terminated() has completed
*
* 这些值之间的数字顺序很重要,以便进行有序的比较。
* The numerical order among these values matters, to allow
* 运行状态随时间单调增加,但不必触及每个状态。转换:
* ordered comparisons. The runState monotonically increases over
* time, but need not hit each state. The transitions are:
*
* RUNNING -> SHUTDOWN
* 调用shutdown()时,可能隐含在finalize()中
* On invocation of shutdown(), perhaps implicitly in finalize()
*
* (RUNNING or SHUTDOWN) -> STOP
* On invocation of shutdownNow()
*
* SHUTDOWN -> TIDYING
* When both queue and pool are empty 队列和池都为空
*
* STOP -> TIDYING
* When pool is empty
*
* TIDYING -> TERMINATED
* terminated()方法调用完成
* When the terminated() hook method has completed
*
* 当状态达到TERMINATED时,在awaitterminate()中等待的线程将返回。
* Threads waiting in awaitTermination() will return when the
* state reaches TERMINATED.
*
* 检测从SHUTDOWN过渡到TIDYING不如你想的简单,因为队列可能成为空后非空,反之亦然在SHUTDOWN状态,
* 但我们只能终止,如果在看到它是空的,我们看到workerCount 0(有时需要复核,见下文)。
* Detecting the transition from SHUTDOWN to TIDYING is less
* straightforward than you'd like because the queue may become
* empty after non-empty and vice versa during SHUTDOWN state, but
* we can only terminate if, after seeing that it is empty, we see
* that workerCount is 0 (which sometimes entails a recheck -- see
* below).
*/
// ctlOf(RUNNING, 0) = RUNNING -> 0b11100000000000000000000000000000
// 即: 初始状态为 RUNNING, workerCount = 0
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
// Integer.SIZE = 32 , COUNT_BITS = 29
private static final int COUNT_BITS = Integer.SIZE - 3;
// CAPACITY = 0b00011111111111111111111111111111
// ctl.get() & CAPACITY 的结果就是 workerCount
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
// runState is stored in the high-order bits runState以高阶位存储
// COUNT_BITS = 29
// -1 的二进制表示为 0b11111111111111111111111111111111 (正数取反 + 1)
// 只有RUNNING 的值小于0,所以判断状态是否为RUNNING,只需要判断状态是否小于0就可以了
// RUNNING = 0b11100000000000000000000000000000
private static final int RUNNING = -1 << COUNT_BITS;
// SHUTDOWN = 0b00000000000000000000000000000000
private static final int SHUTDOWN = 0 << COUNT_BITS;
// STOP = 0b00100000000000000000000000000000
private static final int STOP = 1 << COUNT_BITS;
// TIDYING = 0b01000000000000000000000000000000
private static final int TIDYING = 2 << COUNT_BITS;
// TERMINATED = 0b01100000000000000000000000000000
private static final int TERMINATED = 3 << COUNT_BITS;
// Packing and unpacking ctl
// 计算状态值 (取c高三位的值)
private static int runStateOf(int c) { return c & ~CAPACITY; }
// 计算workerCount (取c低29位的值)
private static int workerCountOf(int c) { return c & CAPACITY; }
private static int ctlOf(int rs, int wc) { return rs | wc; }
/*
* Bit field accessors that don't require unpacking ctl.
* These depend on the bit layout and on workerCount being never negative.
*/
private static boolean runStateLessThan(int c, int s) {
return c < s;
}
private static boolean runStateAtLeast(int c, int s) {
return c >= s;
}
private static boolean isRunning(int c) {
// 判断状态是否小于0,只有RUNNING才小于0
return c < SHUTDOWN;
}
/**
* Attempts to CAS-increment the workerCount field of ctl.
*/
private boolean compareAndIncrementWorkerCount(int expect) {
// 使用CAS把值 + 1
return ctl.compareAndSet(expect, expect + 1);
}
/**
* Attempts to CAS-decrement the workerCount field of ctl.
*/
// workerCount 计数 -1
private boolean compareAndDecrementWorkerCount(int expect) {
return ctl.compareAndSet(expect, expect - 1);
}
/**
* 这仅在线程突然终止时调用(请参阅processWorkerExit)。其他衰减在getTask中执行。
* Decrements the workerCount field of ctl. This is called only on
* abrupt termination of a thread (see processWorkerExit). Other
* decrements are performed within getTask.
*/
private void decrementWorkerCount() {
// workerCount 计数 -1,直到成功为止
do {} while (! compareAndDecrementWorkerCount(ctl.get()));
}
/**
* 用于保存任务并将任务交给工作线程的队列。
* The queue used for holding tasks and handing off to worker
* 我们不需要workQueue.poll()返回null就一定意味着workQueue.isEmpty(),
* 因此仅依赖isEmpty来查看队列是否为空(例如,在决定是否从SHUTDOWN过渡到TIDYING时必须这样做)。
* threads. We do not require that workQueue.poll() returning
* null necessarily means that workQueue.isEmpty(), so rely
* solely on isEmpty to see if the queue is empty (which we must
* do for example when deciding whether to transition from
* SHUTDOWN to TIDYING).
* 这适用于特定目的的队列,比如允许poll()返回null的DelayQueues,即使它稍后可能在延迟过期时返回非null。
* This accommodates special-purpose
* queues such as DelayQueues for which poll() is allowed to
* return null even if it may later return non-null when delays
* expire.
*/
private final BlockingQueue<Runnable> workQueue;
/**
* 锁定访问workers集合和相关的簿记。
* Lock held on access to workers set and related bookkeeping.
* 虽然我们可以使用某种类型的并发集,它通常比使用锁更好。
* While we could use a concurrent set of some sort, it turns out
* to be generally preferable to use a lock.
* 其中一个原因是,它连续interruptIdleWorkers(),从而避免了不必要的中断风暴,特别是在shutdown期间。
* (interruptIdleWorkers()中断线程需要先获取mainLock锁,从而避免连续调用shutdown()引起中断风暴)
* Among the reasons is
* that this serializes interruptIdleWorkers, which avoids
* unnecessary interrupt storms, especially during shutdown.
* 另一方面,退出的线程将同时中断那些尚未中断的线程。
* Otherwise exiting threads would concurrently interrupt those
* that have not yet interrupted. It also simplifies some of the
* 它还简化了一些相关的统计数据簿记的largestPoolSize等。
* associated statistics bookkeeping of largestPoolSize etc. We
* 我们也在shutdown和shutdownNow时保持主锁,以确保workers集合是稳定的,同时分别检查中断和实际中断的权限。
* also hold mainLock on shutdown and shutdownNow, for the sake of
* ensuring workers set is stable while separately checking
* permission to interrupt and actually interrupting.
*/
/**
* 使用锁而不使用concurrentMap的原因: 1、interruptIdleWorkers()中断线程需要先获取mainLock锁,从而避免连续调用
* shutdown()引起中断风暴;2、避免退出的线程同时中断那些尚未中断的线程;3、简化了一些相关的统计数据,比如
* largestPoolSize等;4、在shutdown()和shutdownNow()时保持主锁,以确保workers集合是稳定的(不会增加、删除),
* 同时分别检查中断和实际中断的权限
*/
private final ReentrantLock mainLock = new ReentrantLock();
/**
* 包含池中的所有工作线程集合。只有在持有主锁时才能访问。
* Set containing all worker threads in pool. Accessed only when
* holding mainLock.
*/
private final HashSet<Worker> workers = new HashSet<Worker>();
/**
* 支持awaitTermination()方法,使线程可以在此等待队列上进行等待
* Wait condition to support awaitTermination
*/
private final Condition termination = mainLock.newCondition();
/**
* 跟踪达到的最大池大小。仅在主锁下访问。
* Tracks largest attained pool size. Accessed only under
* mainLock.
*/
// 记录线程池达到的最大线程数
private int largestPoolSize;
/**
* 完成任务的计数器。仅在工作线程终止时更新。仅在主锁下访问。
* Counter for completed tasks. Updated only on termination of
* worker threads. Accessed only under mainLock.
*/
private long completedTaskCount;
/*
* All user control parameters are declared as volatiles so that
* ongoing actions are based on freshest values, but without need
* for locking, since no internal invariants depend on them
* changing synchronously with respect to other actions.
*/
/**
* 创建线程的工厂。所有的线程使用这个工厂进行创建(通过方法 addWorker()).
* Factory for new threads. All threads are created using this
* factory (via method addWorker).
* 所有调用者必须为addWorker失败做好准备,这可能反映了系统或用户的策略限制了线程的数量。
* All callers must be prepared
* for addWorker to fail, which may reflect a system or user's
* policy limiting the number of threads. Even though it is not
* 即使它不是一个错误,失败的创建线程可能会导致新的任务被拒绝或现有的任务留在队列中。
* treated as an error, failure to create threads may result in
* new tasks being rejected or existing ones remaining stuck in
* the queue.
*
* 我们更进一步,保留池不变量,即使在出现OutOfMemoryError等错误时也是如此,
* 这些错误可能是在尝试创建线程时抛出的。
* We go further and preserve pool invariants even in the face of
* errors such as OutOfMemoryError, that might be thrown while
* trying to create threads.
*
* 由于Thread.start需要分配本机堆栈,这种错误相当常见,用户将希望执行清理池关闭以进行清理。
* Such errors are rather common due to
* the need to allocate a native stack in Thread.start, and users
* will want to perform clean pool shutdown to clean up. There
* 可能会有足够的内存来完成清理代码,而不会遇到另一个OutOfMemoryError错误。
* will likely be enough memory available for the cleanup code to
* complete without encountering yet another OutOfMemoryError.
*/
private volatile ThreadFactory threadFactory;
/**
* 处理程序在执行中饱和或关闭时调用。
* Handler called when saturated or shutdown in execute.
*/
private volatile RejectedExecutionHandler handler;
/**
* 等待工作的空闲线程的超时时间(纳秒)。
* Timeout in nanoseconds for idle threads waiting for work.
* 当存在数量超过corePoolSize的线程或allowCoreThreadTimeOut时,线程将使用此超时。
* Threads use this timeout when there are more than corePoolSize
* present or if allowCoreThreadTimeOut. Otherwise they wait
* 否则,他们将永远等待新的工作。
* forever for new work.
*/
private volatile long keepAliveTime;
/**
* 如果为false(默认值),核心线程即使在空闲时也保持活动状态。
* If false (default), core threads stay alive even when idle.
* 如果true,核心线程使用keepAliveTime来超时等待工作。
* If true, core threads use keepAliveTime to time out waiting
* for work.
*/
private volatile boolean allowCoreThreadTimeOut;
/**
* Core pool size is the minimum number of workers to keep alive
* (and not allow to time out etc) unless allowCoreThreadTimeOut
* is set, in which case the minimum is zero.
*/
// 核心线程数量
private volatile int corePoolSize;
/**
* 注意,实际的最大值是由CAPACITY内部限制的。
* Maximum pool size. Note that the actual maximum is internally
* bounded by CAPACITY.
*/
// 最大线程数量
private volatile int maximumPoolSize;
/**
* The default rejected execution handler
*/
private static final RejectedExecutionHandler defaultHandler =
new AbortPolicy();
/**
* Permission required for callers of shutdown and shutdownNow.
* We additionally require (see checkShutdownAccess) that callers
* have permission to actually interrupt threads in the worker set
* (as governed by Thread.interrupt, which relies on
* ThreadGroup.checkAccess, which in turn relies on
* SecurityManager.checkAccess). Shutdowns are attempted only if
* these checks pass.
*
* All actual invocations of Thread.interrupt (see
* interruptIdleWorkers and interruptWorkers) ignore
* SecurityExceptions, meaning that the attempted interrupts
* silently fail. In the case of shutdown, they should not fail
* unless the SecurityManager has inconsistent policies, sometimes
* allowing access to a thread and sometimes not. In such cases,
* failure to actually interrupt threads may disable or delay full
* termination. Other uses of interruptIdleWorkers are advisory,
* and failure to actually interrupt will merely delay response to
* configuration changes so is not handled exceptionally.
*/
private static final RuntimePermission shutdownPerm =
new RuntimePermission("modifyThread");
/**
* 类Worker主要维护运行任务的线程的中断控制状态,以及其他次要的记帐功能(记录完成任务数量)。
* Class Worker mainly maintains interrupt control state for
* threads running tasks, along with other minor bookkeeping.
* 该类投机地扩展了AbstractQueuedSynchronizer,以简化获取和释放每个任务执行的锁。
* This class opportunistically extends AbstractQueuedSynchronizer
* to simplify acquiring and releasing a lock surrounding each
* 这可以防止一些中断,这些中断的目的是唤醒正在等待任务的工作线程,而不是中断正在运行的任务。
* task execution. This protects against interrupts that are
* intended to wake up a worker thread waiting for a task from
* instead interrupting a task being run.
* 我们实现了一个简单的不可重入互斥锁,而不是使用ReentrantLock,因为我们不希望工作任务
* 在调用诸如setCorePoolSize之类的池控制方法时能够重新获得锁。
* We implement a simple
* non-reentrant mutual exclusion lock rather than use
* ReentrantLock because we do not want worker tasks to be able to
* reacquire the lock when they invoke pool control methods like
* setCorePoolSize.
* 另外,为了在线程真正开始运行任务之前禁止中断,我们将锁状态初始化为一个负值,
* 并在启动时清除它(在runWorker中)。
* Additionally, to suppress interrupts until
* the thread actually starts running tasks, we initialize lock
* state to a negative value, and clear it upon start (in
* runWorker).
*/
private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable
{
/**
* This class will never be serialized, but we provide a
* serialVersionUID to suppress a javac warning.
*/
private static final long serialVersionUID = 6138294804551838833L;
// 此 worker运行的线程,如果线程工厂失败为null
/** Thread this worker is running in. Null if factory fails. */
final Thread thread;
// 要运行的初始任务。 可能为null
/** Initial task to run. Possibly null. */
Runnable firstTask;
// 线程任务计数器
/** Per-thread task counter */
volatile long completedTasks;
/**
* Creates with given first task and thread from ThreadFactory.
* @param firstTask the first task (null if none)
*/
// 创建一个worker,锁的状态值为 -1,并初始化 firstTask、thread
Worker(Runnable firstTask) {
// 为了在线程真正开始运行任务之前禁止中断
setState(-1); // inhibit interrupts until runWorker 禁止中断,直到运行
this.firstTask = firstTask;
// Runnable 传入 this
this.thread = getThreadFactory().newThread(this);
}
// 将主运行循环委托给外部runWorker
/** Delegates main run loop to outer runWorker */
public void run() {
runWorker(this);
}
// Lock methods
//
// The value 0 represents the unlocked state. 0表示解锁状态
// The value 1 represents the locked state. 1表示锁定状态
protected boolean isHeldExclusively() {
return getState() != 0;
}
// 尝试获取锁
protected boolean tryAcquire(int unused) {
if (compareAndSetState(0, 1)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
// 尝试释放锁, release()方法会调用这个方法
protected boolean tryRelease(int unused) {
setExclusiveOwnerThread(null);
setState(0);
return true;
}
public void lock() { acquire(1); }
public boolean tryLock() { return tryAcquire(1); }
public void unlock() { release(1); }
public boolean isLocked() { return isHeldExclusively(); }
// 如果已经启动了,中断线程
void interruptIfStarted() {
Thread t;
// state 的初始值为 -1,运行之前禁止中断
if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
try {
t.interrupt();
} catch (SecurityException ignore) {
}
}
}
}
/*
* Methods for setting control state
*/
/**
* Transitions runState to given target, or leaves it alone if
* already at least the given target.
*
* @param targetState the desired state, either SHUTDOWN or STOP
* (but not TIDYING or TERMINATED -- use tryTerminate for that)
*/
private void advanceRunState(int targetState) {
for (;;) {
int c = ctl.get();
// 如果状态已经至少过度到 targetState了,那么直接返回
// 否则循环使用CAS设置状态为 targetState,直到成功为止
if (runStateAtLeast(c, targetState) ||
// 取出 workerCount的值,然后再合并状态
ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
break;
}
}
/**
* 转换到TERMINATED状态(SHUTDOWN和池和队列为空)或(STOP和池为空)。
* Transitions to TERMINATED state if either (SHUTDOWN and pool
* and queue empty) or (STOP and pool empty). If otherwise
* 如果有条件终止,但workerCount非零,则中断空闲worker,以确保shutdown信号传播。
* eligible to terminate but workerCount is nonzero, interrupts an
* idle worker to ensure that shutdown signals propagate. This
* 必须在任何可能导致终止的操作之后调用此方法
* method must be called following any action that might make
* termination possible -- reducing worker count or removing tasks
* 减少 workerCount 或者 在shutdown期间从队列中移除任务
* from the queue during shutdown. The method is non-private to
* 该方法是非私有的,允许从ScheduledThreadPoolExecutor进行访问
* allow access from ScheduledThreadPoolExecutor.
*/
// 判断是否满足终止条件,满足则终止线程池
final void tryTerminate() {
for (;;) {
int c = ctl.get();
if (isRunning(c) || // 判断状态是否是RUNNING
runStateAtLeast(c, TIDYING) || // 判断状态为 TIDYING / TERMINATED
// workQueue不为空线程池不能终止
(runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty())) // 状态为 SHUTDOWN && workQueue不为空
// 以上几种情况,方法直接返回
return;
// ----- 线程执行到这里说明: 线程状态为:STOP / SHUTDOWN && workQueue为空 --------
// 还有worker存在
if (workerCountOf(c) != 0) { // Eligible to terminate 可以进行终止
// ONLY_ONE = true, 中断一个空闲的线程 (), 以确保shutdown信号传播
// 如果线程A和线程B同时在等待任务,而线程C往队列中添加了一个任务,然后在调用notEmpty.signal()方法之前,线程D执行了,
// 调用了线程池的shutdown()方法,然后把线程A和线程B都中断了,线程在等待队列中被中断会 清除中断状态 并抛出中断异常,而这
// 个异常在getTask()方法中被捕获了,因此线程A和线程B继续执行for循环, 而此时队列中有且只有一个任务,所以
// rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())判断结果为false,并且线程A和线程B都通过了判断,然后都从
// 队列中取获取任务,那么只有一个线程(比如线程A)可以成功取得任务,而另一个线程(比如线程B)还会在等待队列中进行等待,那么线程
// A退出的时候,需要唤醒线程B,否则线程B就一直等待。所以,中断一个空闲的线程 (),以确保shutdown()信号传播,如果找到的第一个
// worker不是空闲状态的,那么不需要往下唤醒,忙碌的线程退出时会往下唤醒。
interruptIdleWorkers(ONLY_ONE);
return;
}
// 没有 worker存在了,当没有worker存在时,使用CAS把Executor状态设置为 TIDYING
final ReentrantLock mainLock = this.mainLock;
// termination 的mainLock的一个等待队列,获取锁才能调用 termination.signalAll() 方法
mainLock.lock();
try {
// ctlOf(TIDYING, 0) = TIDYING,使用CAS 把线程池状态设置为 TIDYING
if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
try {
// CAS成功调用 terminated()方法,默认方法实现是空的,用于子类扩展
terminated();
} finally {
// ctlOf(TERMINATED, 0) = TERMINATED, 设置Executor状态为 TERMINATED
ctl.set(ctlOf(TERMINATED, 0));
// 把termination 等待队列中的所有节点移动到同步队列中
termination.signalAll();
}
return;
}
} finally {
// 释放锁,释放锁会唤醒同步队列中的阻塞线程
mainLock.unlock();
}
// CAS 失败,进行重试
// else retry on failed CAS
}
}
/*
* Methods for controlling interrupts to worker threads.
*/
/**
* If there is a security manager, makes sure caller has
* permission to shut down threads in general (see shutdownPerm).
* If this passes, additionally makes sure the caller is allowed
* to interrupt each worker thread. This might not be true even if
* first check passed, if the SecurityManager treats some threads
* specially.
*/
private void checkShutdownAccess() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(shutdownPerm);
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (Worker w : workers)
security.checkAccess(w.thread);
} finally {
mainLock.unlock();
}
}
}
/**
* 中断所有线程,即使是活动的。忽略SecurityExceptions
* Interrupts all threads, even if active. Ignores SecurityExceptions
* 在这种情况下,一些线程可以保持不中断
* (in which case some threads may remain uninterrupted).
*/
private void interruptWorkers() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// 中断所有已启动的worker (未启动的线程无法进行中断,调用interrupt(),中断状态还是false)
for (Worker w : workers)
w.interruptIfStarted();
} finally {
mainLock.unlock();
}
}
/**
* 中断可能正在等待任务的线程(如未被锁定),因此它们可以检查终止或配置更改。
* Interrupts threads that might be waiting for tasks (as
* indicated by not being locked) so they can check for
* termination or configuration changes. Ignores
* 在这种情况下,一些线程可以保持不中断
* SecurityExceptions (in which case some threads may remain
* uninterrupted).
* true,最多中断一个worker.
* @param onlyOne If true, interrupt at most one worker. This is
* 仅当启用终止功能但还有其他workers时,才从tryTerminate调用此方法。
* called only from tryTerminate when termination is otherwise
* enabled but there are still other workers. In this case, at
* 在这种情况下,在所有线程都在等待的情况下,最多中断一个等待worker来传播关闭信号。
* most one waiting worker is interrupted to propagate shutdown
* signals in case all threads are currently waiting.
* 中断任意线程将确保自关闭开始以来新到达的workers也将最终退出。
* Interrupting any arbitrary thread ensures that newly arriving
* workers since shutdown began will also eventually exit.
* 为了保证最终的终止,它总是只中断一个空闲的工作,但是shutdown()中断所有空闲的工作,
* 这样冗余的workers就可以立即退出,而不是等待一个掉队的任务完成。
* To guarantee eventual termination, it suffices to always
* interrupt only one idle worker, but shutdown() interrupts all
* idle workers so that redundant workers exit promptly, not
* waiting for a straggler task to finish.
*/
// onlyOne = true,只获取workers中的第一个worker,若线程已中断/不是空闲状态则不进行中断,直接返回
private void interruptIdleWorkers(boolean onlyOne) {
final ReentrantLock mainLock = this.mainLock;
// 获取锁,避免连续调用 interruptIdleWorkers()而引起中断风暴
mainLock.lock();
try {
// 遍历所有的workers
for (Worker w : workers) {
Thread t = w.thread;
// 若线程还未中断,并且尝试获取锁成功, 若获取锁失败说明线程不是空闲的
if (!t.isInterrupted() && w.tryLock()) {
try {
// 中断线程
t.interrupt();
} catch (SecurityException ignore) {
// 忽略SecurityException
} finally {
w.unlock();
}
}
// 若onlyOne = true,则不管是否有中断一个线程(可能获取锁失败)都直接返回
if (onlyOne)
break;
}
} finally {
mainLock.unlock();
}
}
/**
* 常见的interruptIdleWorkers形式,以避免必须记住布尔参数的含义。
* Common form of interruptIdleWorkers, to avoid having to
* remember what the boolean argument means.
*/
private void interruptIdleWorkers() {
// 中断所有空闲的线程
interruptIdleWorkers(false);
}
private static final boolean ONLY_ONE = true;
/*
* Misc utilities, most of which are also exported to
* ScheduledThreadPoolExecutor
*/
/**
* 调用拒绝处理器执行 command任务
* Invokes the rejected execution handler for the given command.
* 权限为同一个包级别,可以被 ScheduledThreadPoolExecutor调用
* Package-protected for use by ScheduledThreadPoolExecutor.
*/
// 任务拒绝处理
final void reject(Runnable command) {
handler.rejectedExecution(command, this);
}
/**
* 在关闭调用时执行运行状态转换后的任何进一步清理。
* Performs any further cleanup following run state transition on
* invocation of shutdown. A no-op here, but used by
* 这里没有任何实现,但是ScheduledThreadPoolExecutor使用它来取消延迟的任务。
* ScheduledThreadPoolExecutor to cancel delayed tasks.
*/
void onShutdown() {
}
/**
* ScheduledThreadPoolExecutor需要的状态检查,以在shutdown期间启用正在运行的任务。
* State check needed by ScheduledThreadPoolExecutor to
* enable running tasks during shutdown.
*
* @param shutdownOK true if should return true if SHUTDOWN
*/
// 判断线程池状态是否是 RUNNING || 在 shutdownOK = true的情况下,线程池的状态是否是 SHUTDOWN
final boolean isRunningOrShutdown(boolean shutdownOK) {
int rs = runStateOf(ctl.get());
return rs == RUNNING || (rs == SHUTDOWN && shutdownOK);
}
/**
* 将任务队列排入新列表,通常使用drainTo。
* Drains the task queue into a new list, normally using
* 但是,如果队列是一个DelayQueue或任何其他类型的队列,poll或drainTo可能无法删除某些元素,
* 那么它将逐个删除这些元素。
* drainTo. But if the queue is a DelayQueue or any other kind of
* queue for which poll or drainTo may fail to remove some
* elements, it deletes them one by one.
*/
private List<Runnable> drainQueue() {
BlockingQueue<Runnable> q = workQueue;
ArrayList<Runnable> taskList = new ArrayList<Runnable>();
// 删除队列中的所有元素,并放入 taskList
q.drainTo(taskList);
// 队列是一个DelayQueue或任何其他类型的队列, poll或drainTo可能无法删除某些元素( 因此下面用remove() )
if (!q.isEmpty()) {
// 把队列中的所有数组放入数组,然后进行遍历
for (Runnable r : q.toArray(new Runnable[0])) {
// 移除元素,并放入 taskList
if (q.remove(r))
taskList.add(r);
}
}
return taskList;
}
/*
* Methods for creating, running and cleaning up after workers
*/
/**
* 检查是否可以根据当前池状态和给定的界限(核心或最大值)添加新worker。
* Checks if a new worker can be added with respect to current
* pool state and the given bound (either core or maximum). If so,
* the worker count is adjusted accordingly, and, if possible, a
* new worker is created and started, running firstTask as its
* 如果池已停止或有资格关闭,则此方法返回false。如果线程工厂在被请求时没有创建线程,那么它也会返回false。
* first task. This method returns false if the pool is stopped or
* eligible to shut down. It also returns false if the thread
* factory fails to create a thread when asked. If the thread
* creation fails, either due to the thread factory returning
* null, or due to an exception (typically OutOfMemoryError in
* Thread.start()), we roll back cleanly.
*
* @param firstTask the task the new thread should run first (or
* null if none). Workers are created with an initial first task
* (in method execute()) to bypass queuing when there are fewer
* than corePoolSize threads (in which case we always start one),
* or when the queue is full (in which case we must bypass queue).
* Initially idle threads are usually created via
* prestartCoreThread or to replace other dying workers.
*
* @param core if true use corePoolSize as bound, else
* 这里使用布尔指示符而不是值来确保在检查其他池状态后读取新值
* maximumPoolSize. (A boolean indicator is used here rather than a
* value to ensure reads of fresh values after checking other pool
* state).
* @return true if successful
*/
// 如果线程池停止了,或者线程数量已经达到最大,返回false
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
// 计算状态值 (取c高三位的值)
int rs = runStateOf(c);
// Check if queue empty only if necessary.
// 如果线程池状态为: STOP/TIDYING/TERMINATED
// 或者线程池状态为 SHUTDOWN 但是 firstTask != null 或者 firstTask = null,但是 workQueue为空
// 方法直接返回false。即如果线程池已经关闭了,则不能再添加新的任务,新的worker只能去执行workQueue中的任务
// 等价于:rs >= SHUTDOWN && (rs != SHUTDOWN || firstTask != null || workQueue.isEmpty())
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
for (;;) {
int wc = workerCountOf(c);
// wc >= CAPACITY 说明线程池状态不是 RUNNING 和 SHUTDOWN,或者线程池数量已经达到最大限制
// || 超出配置的线程数量
// SHUTDOWN = 0 << COUNT_BITS, SHUTDOWN 的状态值是0
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
// 使用CAS把值 + 1, workerCount增加
if (compareAndIncrementWorkerCount(c))
// 检查通过,跳出外部循环
break retry;
c = ctl.get(); // Re-read ctl
// 判断线程池状态是否已经改变
if (runStateOf(c) != rs)
// 线程池状态变了,继续外部循环
continue retry;
// 由于workerCount 改变而导致CAS失败,重试内循环
// else CAS failed due to workerCount change; retry inner loop
}
}
// --- 上面已经判断过可以添加 worker了 ----------
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
// 创建一个worker,锁的状态值为 -1,并初始化 firstTask,然后创建一个线程
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
// 获取锁
mainLock.lock();
try {
// Recheck while holding lock. 持有锁时重新检查。
// Back out on ThreadFactory failure or if
// shut down before lock acquired. 退出 当ThreadFactory故障,或者在获取锁之前关闭。
int rs = runStateOf(ctl.get());
// rs < SHUTDOWN 说明线程池的状态为:RUNNING || 线程池状态为 SHUTDOWN,并且 firstTask = null
// 前面判断线程池状态时,可能状态还是RUNNING,因此现在状态为 SHUTDOWN时,firstTask可能不为null
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
// 判断线程是否已经启动,如果已经启动,抛出异常
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
// 把Worker 添加到workers集合
workers.add(w);
// 记录线程池达到的最大线程数
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
// 添加 worker 成功
workerAdded = true;
}
} finally {
// 解锁
mainLock.unlock();
}
if (workerAdded) {
// 启动线程
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
// 添加 worker失败操作
addWorkerFailed(w);
}
return workerStarted;
}
/**
* 回滚工作线程创建。
* Rolls back the worker thread creation.
* 将 worker从 workers中移除,如果存在的话
* - removes worker from workers, if present
* workerCount -1
* - decrements worker count
* 重新检查终止,以防这个worker的存在导致termination挂起
* - rechecks for termination, in case the existence of this
* worker was holding up termination
*/
// Worker 添加到 Workers之前,就已经把 workerCount的计数增加了,因此如果线程池关闭了,
// 有可能因为Worker创建失败/添加失败但是 workerCount计数增加而导致线程池无法终止
private void addWorkerFailed(Worker w) {
final ReentrantLock mainLock = this.mainLock;
// 获取锁
mainLock.lock();
try {
if (w != null)
// 从 workers中移除这个worker,如果存在的话
workers.remove(w);
// workerCount 计数 -1,直到成功为止
decrementWorkerCount();
// 尝试终止线程池
// Worker 添加到 Workers之前,就已经把 workerCount的计数增加了,因此如果线程池关闭了,
// 由于workerCount不为0, 从而导致线程池无法终止
tryTerminate();
} finally {
// 解锁
mainLock.unlock();
}
}
/**
* Performs cleanup and bookkeeping for a dying worker. Called
* 仅从工作线程调用。除非completedAbruptly被设置,否则假定workerCount已经被调整以考虑退出。
* only from worker threads. Unless completedAbruptly is set,
* assumes that workerCount has already been adjusted to account
* for exit.
* 此方法从工作集中移除线程,如果线程因用户任务异常而退出,或者运行的工作线程小于corePoolSize,
* 或者队列非空但没有工作线程,则可能终止池或替换工作线程。
* This method removes thread from worker set, and
* possibly terminates the pool or replaces the worker if either
* it exited due to user task exception or if fewer than
* corePoolSize workers are running or queue is non-empty but
* there are no workers.
*
* @param w the worker
* @param completedAbruptly if the worker died due to user exception
*/
private void processWorkerExit(Worker w, boolean completedAbruptly) {
// completedAbruptly = true,说明 workerCount还没有调整,getTask()返回null会调整
// workerCount,然后会设置 completedAbruptly = false
if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
// workerCount 计数 -1
decrementWorkerCount();
final ReentrantLock mainLock = this.mainLock;
// 获取锁
mainLock.lock();
try {
// 更新线程池完成任务计数
completedTaskCount += w.completedTasks;
// 移除worker
workers.remove(w);
} finally {
mainLock.unlock();
}
// 判断线程池是否应该终止,如果条件满足,终止线程池
tryTerminate();
int c = ctl.get();
// 判断线程池状态是否为: RUNNING / SHUTDOWN
if (runStateLessThan(c, STOP)) {
if (!completedAbruptly) {
// 判断线程池应有的最少线程数
int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
// 如果队列中还有任务,那么最少要有一个worker
if (min == 0 && ! workQueue.isEmpty())
min = 1;
if (workerCountOf(c) >= min) {
// 不需要替换worker
return; // replacement not needed
}
}
// completedAbruptly = true,线程突然终止,说明执行beforeExecute() / task.run() / afterExecute()
// 时出现了异常,或者线程数量太少了,那么添加 worker。 core = false 说明不超过maximumPoolSize即可添加worker
// 如果线程A执行任务异常了,workerCount - 1之后刚好小于核心线程数,如果这时候线程B添加了一个worker,达到了核心线程数,
// 而这里又添加了一个worker, 如果 corePoolSize < maximumPoolSize,那么 worker就会超过核心线程数,即使队列还没有满
addWorker(null, false);
}
}
/**
* 执行阻塞或定时等待任务,取决于当前的配置设置,或返回null,如果这个worker必须退出,由于以下任何一点:
* Performs blocking or timed wait for a task, depending on
* current configuration settings, or returns null if this worker
* must exit because of any of:
* workers数量超过 maximumPoolSize
* 1. There are more than maximumPoolSize workers (due to
* a call to setMaximumPoolSize).
*
* poll状态为STOP
* 2. The pool is stopped.
*
* poll状态为workers,并且队列为空
* 3. The pool is shutdown and the queue is empty.
*
* 这个worker超时等待一个任务,超时的worker在超时等待之前和之后都可能终止(即{@code allowCoreThreadTimeOut ||
* workerCount > corePoolSize}),如果队列不是空的,那么这个worker不是池中的最后一个线程。
* 4. This worker timed out waiting for a task, and timed-out
* workers are subject to termination (that is,
* {@code allowCoreThreadTimeOut || workerCount > corePoolSize})
* both before and after the timed wait, and if the queue is
* non-empty, this worker is not the last thread in the pool.
*
* 返回task,或者返回null表示这个worker必须退出,在这种情况下workerCount递减
* @return task, or null if the worker must exit, in which case
* workerCount is decremented
*/
private Runnable getTask() {
boolean timedOut = false; // Did the last poll() time out?
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
// 如果线程池状态为: STOP/TIDYING/TERMINATED,或者线程池状态为 SHUTDOWN 但是队列为空,那么worker必须退出
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
// workerCount 计数 -1
decrementWorkerCount();
// 返回null,表示 worker必须退出
return null;
}
int wc = workerCountOf(c);
// Are workers subject to culling?
// wc > corePoolSize 线程数量是否大于核心线程数量
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
// wc > maximumPoolSize 如果线程数量大于最大线程数量
// timed && timedOut 设置allowCoreThreadTimeOut 或者 线程数量大于核心线程数量,并且已经超时了
// wc > 1 || workQueue.isEmpty() 线程数量 > 1 或者 队列为空
// 如果线程数量大于了核心线程数量,那么所有的线程都会在指定的时间内获取任务,如果获取任务超时了,
// 那么使用CAS把workerCount 计数 -1,成功 worker退出,失败继续判断worker是否应该退出。所以如果
// 线程数量大于核心线程数量,那么再指定的时间内没有获取到任务,线程会关闭,直到等于核心线程数量。
// 如果设置了 allowCoreThreadTimeOut = true,那么线程数量可能会减到0
// 线程数量大于最大线程数量 (maximumPoolSize是可以通过set方法修改的,所以可能会有 wc > maximumPoolSize)
if ((wc > maximumPoolSize || (timed && timedOut)) // 线程超过maximumPoolSize || 已超时
&& (wc > 1 || workQueue.isEmpty())) { // 线程数量 > 1 || 队列为空
// 使用CAS把 workerCount 计数 -1。使用CAS的原因:线程数量会变化,此时可能不再满足 wc > corePoolSize
// 或者不再满足 wc > maximumPoolSize,这种情况下 worker 不能退出
if (compareAndDecrementWorkerCount(c))
// CAS成功,返回null,表示 worker必须退出
return null;
// CAS失败,继续循环
continue;
}
try {
// workQueue.take() 检索并移除这个队列的第一个元素,如果有必要则进行等待,直到有一个元素可用
// 如果线程被中断了,会抛出 InterruptedException
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : // 将在指定的等待时间等待可用元素
workQueue.take();
if (r != null)
// 获取到任务,返回
return r;
// 没有获取到,说明超时了
timedOut = true;
} catch (InterruptedException retry) {
// 线程被中断, 获取任务时不接受线程中断
timedOut = false;
}
}
}
/**
* 主worker运行循环。重复从队列获取任务并执行它们,同时处理一些问题:
* Main worker run loop. Repeatedly gets tasks from queue and
* executes them, while coping with a number of issues:
*
* 我们可能从一个初始任务开始,在这种情况下,我们不需要得到第一个。
* 1. We may start out with an initial task, in which case we
* don't need to get the first one. Otherwise, as long as pool is
* 否则,只要池在运行,我们就从getTask获取任务。
* running, we get tasks from getTask. If it returns null then the
* 如果返回null,则工作进程将由于更改池状态或配置参数而退出。
* worker exits due to changed pool state or configuration
* 其他出口由外部代码中的异常抛出导致,在这种情况下completedAbruptly持有,
* 这通常会导致processWorkerExit替换这个线程。
* parameters. Other exits result from exception throws in
* external code, in which case completedAbruptly holds, which
* usually leads processWorkerExit to replace this thread.
*
* 在运行任何任务之前,锁被获取以防止任务执行过程中其他池中断,然后我们确保这个线程
* 没有设置中断状态,除非池停止。
* 2. Before running any task, the lock is acquired to prevent
* other pool interrupts while the task is executing, and then we
* ensure that unless pool is stopping, this thread does not have
* its interrupt set.
*
* 每个任务运行之前都有一个对beforeExecute的调用,这可能会抛出一个异常,在这种情况下,
* 我们在不处理任务的情况下导致线程死亡(用completedAbruptly的值为 true 中断循环)。
* 3. Each task run is preceded by a call to beforeExecute, which
* might throw an exception, in which case we cause thread to die
* (breaking loop with completedAbruptly true) without processing
* the task.
*
* 假设beforeExecute正常完成,我们运行这个任务,收集它抛出的任何异常并发送给afterExecute。
* 4. Assuming beforeExecute completes normally, we run the task,
* gathering any of its thrown exceptions to send to afterExecute.
* 我们分别处理RuntimeException、Error(规范中保证我们会捕捉到这两个错误)和任意的可抛出对象。
* We separately handle RuntimeException, Error (both of which the
* specs guarantee that we trap) and arbitrary Throwables.
* 因为我们不能在Runnable.run中重新抛出Throwables,所以我们在抛出时将它们封装在
* Errors中(到线程的UncaughtExceptionHandler)。
* Because we cannot rethrow Throwables within Runnable.run, we
* wrap them within Errors on the way out (to the thread's
* UncaughtExceptionHandler). Any thrown exception also
* 任何抛出的异常也会保守地导致线程死亡。
* conservatively causes thread to die.
*
* task.run完成后,我们调用afterExecute,它也可能抛出一个异常,这也会导致线程死亡。
* 5. After task.run completes, we call afterExecute, which may
* also throw an exception, which will also cause thread to
* 根据JLS 14.20,这个异常即使在task.run抛出时也有效。
* die. According to JLS Sec 14.20, this exception is the one that
* will be in effect even if task.run throws.
*
* 异常机制的最终效果是,afterExecute和线程的UncaughtExceptionHandler拥有关于
* 用户代码遇到的任何问题的尽可能准确的信息。
* The net effect of the exception mechanics is that afterExecute
* and the thread's UncaughtExceptionHandler have as accurate
* information as we can provide about any problems encountered by
* user code.
*
* @param w the worker
*/
// 这个方法是由 Worker 调用的
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
// unlock() 把state 值设置为0,而不是 -1。 state初始值是-1,不允许中断,线程启动后调用unlock()才允许中断
w.unlock(); // allow interrupts 允许中断
// completedAbruptly 突然终止
boolean completedAbruptly = true;
try {
// getTask() 获取任务,如果返回null说明worker 应该退出
// getTask() 返回null,(task = getTask()) != null => false,结束 while()循环
while (task != null || (task = getTask()) != null) {
// 获取锁,表示线程处于忙碌状态
w.lock();
// If pool is stopping, ensure thread is interrupted; 如果池停止,确保线程被中断;
// if not, ensure thread is not interrupted. This 如果没有,请确保线程没有被中断
// 这需要在第二种情况下重新检查,以处理清除中断时的shutdownNow竞争
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
// (Thread.interrupted() && runStateAtLeast(ctl.get(), STOP)) 的作用是如果线程池还没有停止,
// 确保线程没有被中断。如果线程被中断了,需要再次检查线程池是否停止了,避免 shutdownNow竞争。
// shutdownNow()先设置线程池状态为STOP,再中断线程,因此如果线程是因为shutdownNow()而中断的,
// 那么runStateAtLeast(ctl.get(), STOP)一定为true
if ((runStateAtLeast(ctl.get(), STOP) || // 线程状态为: STOP / TIDYING / TERMINATED
(Thread.interrupted() && // 检查当前线程是否已经中断,并清除中断状态
runStateAtLeast(ctl.get(), STOP)) ) &&
!wt.isInterrupted()) // 线程没有被中断
// 中断线程,如果线程池状态为 STOP,但是还没有中断到此线程,那么自行中断
wt.interrupt();
try {
// 执行 beforeExecute()
beforeExecute(wt, task);
Throwable thrown = null;
try {
// 执行任务
task.run();
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
// 执行afterExecute()
afterExecute(task, thrown);
}
} finally {
// 如果beforeExecute()抛出异常,或者task 执行失败了,那么不会把task再放回队列
task = null;
// 无论是否执行成功,w.completedTasks + 1
w.completedTasks++;
// 释放锁
w.unlock();
}
}
// beforeExecute、 task.run()、afterExecute 抛出异常了,不会执行到这里
// 如果 getTask() 返回null,那么 workerCount已经-1,设置completedAbruptly = false,
// 那么processWorkerExit()不会再对workerCount进行递减
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
// Public constructors and methods 公共的构造器和方法
/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters and default thread factory and rejected execution handler.
* 使用 Executors 工厂方法之一比使用此通用构造方法方便得多。
* It may be more convenient to use one of the {@link Executors} factory
* methods instead of this general purpose constructor.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* @param maximumPoolSize the maximum number of threads to allow in the
* pool
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* @param unit the time unit for the {@code keepAliveTime} argument
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
* @throws IllegalArgumentException if one of the following holds:<br>
* {@code corePoolSize < 0}<br>
* {@code keepAliveTime < 0}<br>
* {@code maximumPoolSize <= 0}<br>
* {@code maximumPoolSize < corePoolSize}
* @throws NullPointerException if {@code workQueue} is null
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
// 默认使用 AbortPolicy任务拒绝处理器
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters and default rejected execution handler.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* @param maximumPoolSize the maximum number of threads to allow in the
* pool
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* @param unit the time unit for the {@code keepAliveTime} argument
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
* @param threadFactory the factory to use when the executor
* creates a new thread
* @throws IllegalArgumentException if one of the following holds:<br>
* {@code corePoolSize < 0}<br>
* {@code keepAliveTime < 0}<br>
* {@code maximumPoolSize <= 0}<br>
* {@code maximumPoolSize < corePoolSize}
* @throws NullPointerException if {@code workQueue}
* or {@code threadFactory} is null
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}
/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters and default thread factory.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* @param maximumPoolSize the maximum number of threads to allow in the
* pool
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* @param unit the time unit for the {@code keepAliveTime} argument
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
* @param handler the handler to use when execution is blocked
* because the thread bounds and queue capacities are reached
* @throws IllegalArgumentException if one of the following holds:<br>
* {@code corePoolSize < 0}<br>
* {@code keepAliveTime < 0}<br>
* {@code maximumPoolSize <= 0}<br>
* {@code maximumPoolSize < corePoolSize}
* @throws NullPointerException if {@code workQueue}
* or {@code handler} is null
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), handler);
}
/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* @param maximumPoolSize the maximum number of threads to allow in the
* pool
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* @param unit the time unit for the {@code keepAliveTime} argument
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
* @param threadFactory the factory to use when the executor
* creates a new thread
* @param handler the handler to use when execution is blocked
* because the thread bounds and queue capacities are reached
* @throws IllegalArgumentException if one of the following holds:<br>
* {@code corePoolSize < 0}<br>
* {@code keepAliveTime < 0}<br>
* {@code maximumPoolSize <= 0}<br>
* {@code maximumPoolSize < corePoolSize}
* @throws NullPointerException if {@code workQueue}
* or {@code threadFactory} or {@code handler} is null
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
// 参数校验
if (corePoolSize < 0 || // 核心线程数可以为0
maximumPoolSize <= 0 || // 最大线程数必须大于0
maximumPoolSize < corePoolSize || // 最大线程数不能小于核心线程数
keepAliveTime < 0) // 激活时间不能小于0
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
/**
* 在将来某个时间执行给定任务。可以在新线程中或者在现有池线程中执行该任务。
* Executes the given task sometime in the future. The task
* may execute in a new thread or in an existing pooled thread.
*
* If the task cannot be submitted for execution, either because this
* executor has been shutdown or because its capacity has been reached,
* the task is handled by the current {@code RejectedExecutionHandler}.
*
* @param command the task to execute
* @throws RejectedExecutionException at discretion of
* {@code RejectedExecutionHandler}, if the task
* cannot be accepted for execution
* @throws NullPointerException if {@code command} is null
*/
// 如果线程池已经关闭,则不能再添加任务
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
/*
* Proceed in 3 steps:
*
* 如果运行的线程小于corePoolSize,则尝试使用给定的command作为第一个任务来启动新线程。
* 1. If fewer than corePoolSize threads are running, try to
* start a new thread with the given command as its first
* 对addWorker的调用会自动地检查runState和workerCount,从而通过返回false来防止在不
* 应该添加线程的情况下添加错误警报。
* task. The call to addWorker atomically checks runState and
* workerCount, and so prevents false alarms that would add
* threads when it shouldn't, by returning false.
*
* 如果一个任务可以成功地排队,那么我们仍然需要再次检查是否应该添加一个线程
* (因为现有的线程在最后一次检查后死亡),或者池在进入这个方法后关闭。
* 2. If a task can be successfully queued, then we still need
* to double-check whether we should have added a thread
* (because existing ones died since last checking) or that
* the pool shut down since entry into this method. So we
* 因此,我们重新检查状态,如果有必要,如果停止,则回滚排队;如果没有,则启动新线程。
* recheck state and if necessary roll back the enqueuing if
* stopped, or start a new thread if there are none.
*
* 如果无法对任务排队,则尝试添加新线程。如果它失败了,我们知道我们被关闭或饱和,因此拒绝任务。
* 3. If we cannot queue task, then we try to add a new
* thread. If it fails, we know we are shut down or saturated
* and so reject the task.
*/
// 如果运行的线程小于corePoolSize,则尝试使用给定的command作为第一个任务来启动新线程
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
// addWorker() 添加 worker,成功返回true,如果线程池停止了,或者线程数量已经达到最大,返回false
if (addWorker(command, true))
return;
c = ctl.get();
}
// 判断线程池状态是否是 RUNNING,如果是,那么把任务添加到队列
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
// 如果线程池状态已经不是RUNNING,那么移除任务
if (! isRunning(recheck) && remove(command))
// 拒绝任务处理
reject(command);
// 如果把任务添加到了队列,而没有worker,那么添加worker去执行任务
// 场景: 如果allowCoreThreadTimeOut = true,核心线程可能都在队列中等待任务,往队列添加任务之前,
// 核心线程雪崩式地全部超时退出了,那么线程池中就没有线程了,因此需要创建线程去处理任务
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
// 如果队列满了,若线程数量少于maximumPoolSize,则创建新的线程进行处理
// 如果无法对任务排队,则尝试添加新线程。如果它失败了,我们知道我们被关闭或饱和,因此拒绝任务。
else if (!addWorker(command, false))
reject(command);
}
/**
* 启动有序关闭,在此过程中执行以前提交的任务,但不接受任何新任务。
* Initiates an orderly shutdown in which previously submitted
* tasks are executed, but no new tasks will be accepted.
* 如果已经关闭,则调用没有其他作用。
* Invocation has no additional effect if already shut down.
*
* 此方法不等待以前提交的任务完成执行。使用{@link #awaitTermination awaitTermination}可以做到这一点。
* <p>This method does not wait for previously submitted tasks to
* complete execution. Use {@link #awaitTermination awaitTermination}
* to do that.
*
* @throws SecurityException {@inheritDoc}
*/
public void shutdown() {
final ReentrantLock mainLock = this.mainLock;
// 保持主锁,以确保workers集合是稳定的(不会增加、删除),同时分别检查中断和实际中断的权限
mainLock.lock();
try {
checkShutdownAccess();
// 修改线程池状态
advanceRunState(SHUTDOWN);
// 中断所有空闲的线程
interruptIdleWorkers();
// 默认实现为空,ScheduledThreadPoolExecutor会重写这个方法
onShutdown(); // hook for ScheduledThreadPoolExecutor
} finally {
// 释放锁
mainLock.unlock();
}
// 判断是否满足终止条件,满足则终止线程池
tryTerminate();
}
/**
* 尝试停止所有的活动执行任务、暂停等待任务的处理,并返回等待执行的任务列表。
* Attempts to stop all actively executing tasks, halts the
* processing of waiting tasks, and returns a list of the tasks
* that were awaiting execution. These tasks are drained (removed)
* 在从此方法返回的任务队列中排空(移除)这些任务。
* from the task queue upon return from this method.
*
* <p>This method does not wait for actively executing tasks to
* terminate. Use {@link #awaitTermination awaitTermination} to
* do that.
*
* 并不保证能够停止正在处理的活动执行任务,但是会尽力尝试。 此实现通过 Thread.interrupt() 取消任务,
* 所以无法响应中断的任何任务可能永远无法终止。
* <p>There are no guarantees beyond best-effort attempts to stop
* processing actively executing tasks. This implementation
* cancels tasks via {@link Thread#interrupt}, so any task that
* fails to respond to interrupts may never terminate.
*
* @throws SecurityException {@inheritDoc}
*/
// 正在执行任务的线程,如果任务没有响应中断,那么任务会一直执行下去
public List<Runnable> shutdownNow() {
List<Runnable> tasks;
final ReentrantLock mainLock = this.mainLock;
// 保持主锁,以确保workers集合是稳定的(不会增加、删除),同时分别检查中断和实际中断的权限
mainLock.lock();
try {
checkShutdownAccess();
// 修改线程池状态为: STOP
advanceRunState(STOP);
// 中断所有已启动的worker
interruptWorkers();
// 删除并返回队列中的所有元素
tasks = drainQueue();
} finally {
mainLock.unlock();
}
// 判断是否满足终止条件,满足则终止线程池
tryTerminate();
return tasks;
}
// 判断线程池是否停用了,只要状态不是RUNNING,那么就返回true
public boolean isShutdown() {
return ! isRunning(ctl.get());
}
/**
* 如果此线程池处于在 shutdown 或 shutdownNow 之后正在终止但尚未完全终止的过程中,则返回 true。
* Returns true if this executor is in the process of terminating
* after {@link #shutdown} or {@link #shutdownNow} but has not
* completely terminated. This method may be useful for
* 关闭之后很长一段时间才报告返回的 true,这可能表示提交的任务已经被忽略或取消中断,
* 导致此执行程序无法正确终止。
* debugging. A return of {@code true} reported a sufficient
* period after shutdown may indicate that submitted tasks have
* ignored or suppressed interruption, causing this executor not
* to properly terminate.
*
* @return {@code true} if terminating but not yet terminated
*/
// 判断线程池是否正在终止,即:状态不是 RUNNING 且不是 TERMINATED
public boolean isTerminating() {
int c = ctl.get();
return ! isRunning(c) && runStateLessThan(c, TERMINATED);
}
// 判断线程池是否已经终止
public boolean isTerminated() {
return runStateAtLeast(ctl.get(), TERMINATED);
}
// 在指定的时间内,等待线程池终止。前提是已经调用shutdown() 或者 shutdownNow()方法,否则返回false
public boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException {
long nanos = unit.toNanos(timeout);
final ReentrantLock mainLock = this.mainLock;
// termination 的mainLock的一个等待队列,获取锁才能调用 termination.awaitNanos(nanos)方法
mainLock.lock();
try {
for (;;) {
// 如果状态已经是TERMINATED, 返回true
if (runStateAtLeast(ctl.get(), TERMINATED))
return true;
// 如果状态还是RUNNING,返回false,不等待
if (nanos <= 0)
return false;
// 如果线程池正在进行终止,那么进入 termination等待队列进行等待
nanos = termination.awaitNanos(nanos);
}
} finally {
mainLock.unlock();
}
}
/**
* 如果线程池已经没有被引用,且没有线程。垃圾回收的时候会调用这个方法
* Invokes {@code shutdown} when this executor is no longer
* referenced and it has no threads.
*/
protected void finalize() {
shutdown();
}
/**
* 设置线程工厂,用于创建新的线程
* Sets the thread factory used to create new threads.
*
* @param threadFactory the new thread factory
* @throws NullPointerException if threadFactory is null
* @see #getThreadFactory
*/
// 设置线程工厂
public void setThreadFactory(ThreadFactory threadFactory) {
if (threadFactory == null)
throw new NullPointerException();
this.threadFactory = threadFactory;
}
/**
* 返回线程工厂用于创建新的线程
* Returns the thread factory used to create new threads.
*
* @return the current thread factory
* @see #setThreadFactory(ThreadFactory)
*/
public ThreadFactory getThreadFactory() {
return threadFactory;
}
/**
* 设置用于未执行任务的新处理程序。
* Sets a new handler for unexecutable tasks.
*
* @param handler the new handler
* @throws NullPointerException if handler is null
* @see #getRejectedExecutionHandler
*/
public void setRejectedExecutionHandler(RejectedExecutionHandler handler) {
if (handler == null)
throw new NullPointerException();
this.handler = handler;
}
/**
* 返回用于未执行任务的当前处理程序。
* Returns the current handler for unexecutable tasks.
*
* @return the current handler
* @see #setRejectedExecutionHandler(RejectedExecutionHandler)
*/
public RejectedExecutionHandler getRejectedExecutionHandler() {
return handler;
}
/**
* 设置核心线程数。此操作将重写构造方法中设置的任何值。如果新值小于当前值,则多余的现有线
* 程将在下一次空闲时终止。如果较大,则在需要时启动新线程来执行这些排队的任务。
* Sets the core number of threads. This overrides any value set
* in the constructor. If the new value is smaller than the
* current value, excess existing threads will be terminated when
* they next become idle. If larger, new threads will, if needed,
* be started to execute any queued tasks.
*
* @param corePoolSize the new core size
* @throws IllegalArgumentException if {@code corePoolSize < 0}
* @see #getCorePoolSize
*/
public void setCorePoolSize(int corePoolSize) {
if (corePoolSize < 0)
throw new IllegalArgumentException();
int delta = corePoolSize - this.corePoolSize;
this.corePoolSize = corePoolSize;
// 如果当前线程数量大于核心线程数量,那么中断空闲线程
if (workerCountOf(ctl.get()) > corePoolSize)
interruptIdleWorkers();
else if (delta > 0) {
// We don't really know how many new threads are "needed".
// As a heuristic, prestart enough new workers (up to new
// core size) to handle the current number of tasks in
// queue, but stop if queue becomes empty while doing so.
// 如果核心线程数量增加了,而队列中还有任务,那么添加新的worker去执行任务,
// 新增的数量为: 增加的线程数量和队列中的任务数量的最小值,但不允许超过核心线程数量
int k = Math.min(delta, workQueue.size());
while (k-- > 0 && addWorker(null, true)) {
// 队列中没有任务了,不加添加worker
if (workQueue.isEmpty())
break;
}
}
}
/**
* 返回核心线程数量
* Returns the core number of threads.
*
* @return the core number of threads
* @see #setCorePoolSize
*/
// 返回配置的核心线程数
public int getCorePoolSize() {
return corePoolSize;
}
/**
* 启动核心线程,使其处于等待工作的空闲状态。
* Starts a core thread, causing it to idly wait for work. This
* 仅当执行新任务时,此操作才重写默认的启动核心线程策略。如果已启动所有核心线程,此方法将返回 false。
* overrides the default policy of starting core threads only when
* new tasks are executed. This method will return {@code false}
* if all core threads have already been started.
*
* @return {@code true} if a thread was started
*/
public boolean prestartCoreThread() {
return workerCountOf(ctl.get()) < corePoolSize &&
addWorker(null, true);
}
/**
* 与prestartCoreThread相同,不同之处是,即使corePoolSize为0,也会至少启动一个线程。
* Same as prestartCoreThread except arranges that at least one
* thread is started even if corePoolSize is 0.
*/
// 如果小于核心数量,那么新增一个worker,即使corePoolSize为0,也会至少启动一个线程。
void ensurePrestart() {
int wc = workerCountOf(ctl.get());
// 如果小于核心数量,那么新增一个worker
if (wc < corePoolSize)
addWorker(null, true);
// 如果核心线程数量为0,那么也新增一个worker
else if (wc == 0)
addWorker(null, false);
}
/**
* 启动所有核心线程,使其处于等待工作的空闲状态。
* Starts all core threads, causing them to idly wait for work. This
* 仅当执行新任务时,此操作才重写默认的启动核心线程策略。
* overrides the default policy of starting core threads only when
* new tasks are executed.
*
* @return the number of threads started
*/
public int prestartAllCoreThreads() {
int n = 0;
// 如果线程池停止了,或者线程数量已经达到核心线程数,返回false
while (addWorker(null, true))
++n;
return n;
}
/**
* 如果此池允许核心线程超时和终止,如果在 keepAlive 时间内没有任务到达,
* 如果需要,在新任务到达时替换,则返回 true。
* Returns true if this pool allows core threads to time out and
* terminate if no tasks arrive within the keepAlive time, being
* replaced if needed when new tasks arrive.
* 当返回 true 时,适用于非核心线程的相同的保持活动策略也同样适用于核心线程。
* 当返回 false(默认值)时,由于没有传入任务,核心线程不会终止。
* When true, the same
* keep-alive policy applying to non-core threads applies also to
* core threads. When false (the default), core threads are never
* terminated due to lack of incoming tasks.
*
* @return {@code true} if core threads are allowed to time out,
* else {@code false}
*
* @since 1.6
*/
public boolean allowsCoreThreadTimeOut() {
return allowCoreThreadTimeOut;
}
/**
* Sets the policy governing whether core threads may time out and
* terminate if no tasks arrive within the keep-alive time, being
* replaced if needed when new tasks arrive. When false, core
* threads are never terminated due to lack of incoming
* tasks. When true, the same keep-alive policy applying to
* non-core threads applies also to core threads. To avoid
* 为了避免持续的线程替换,在设置{@code true}时,keep-alive时间必须大于零。
* continual thread replacement, the keep-alive time must be
* greater than zero when setting {@code true}. This method
* 通常应在池被真正使用之前调用此方法。
* should in general be called before the pool is actively used.
*
* @param value {@code true} if should time out, else {@code false}
* @throws IllegalArgumentException if value is {@code true}
* and the current keep-alive time is not greater than zero
*
* @since 1.6
*/
public void allowCoreThreadTimeOut(boolean value) {
// 为了避免持续的线程替换,在设置{@code true}时,keep-alive时间必须大于零。
if (value && keepAliveTime <= 0)
throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
if (value != allowCoreThreadTimeOut) {
allowCoreThreadTimeOut = value;
if (value)
// 中断空闲的线程
interruptIdleWorkers();
}
}
/**
* 设置允许的最大线程数。此操作将重写构造方法中设置的任何值。如果新值小于当前值,
* 则多余的现有线程将在下一次空闲时终止。
* Sets the maximum allowed number of threads. This overrides any
* value set in the constructor. If the new value is smaller than
* the current value, excess existing threads will be
* terminated when they next become idle.
*
* @param maximumPoolSize the new maximum
* @throws IllegalArgumentException if the new maximum is
* less than or equal to zero, or
* less than the {@linkplain #getCorePoolSize core pool size}
* @see #getMaximumPoolSize
*/
public void setMaximumPoolSize(int maximumPoolSize) {
if (maximumPoolSize <= 0 || maximumPoolSize < corePoolSize)
throw new IllegalArgumentException();
this.maximumPoolSize = maximumPoolSize;
if (workerCountOf(ctl.get()) > maximumPoolSize)
interruptIdleWorkers();
}
/**
* 返回允许的最大线程数。
* Returns the maximum allowed number of threads.
*
* @return the maximum allowed number of threads
* @see #setMaximumPoolSize
*/
public int getMaximumPoolSize() {
return maximumPoolSize;
}
/**
* 设置线程在终止前可以保持空闲的时间限制。如果池中的当前线程数多于核心线程数,
* 在不处理任务的情况下等待这一时间段之后,多余的线程将被终止。此操作将重写构造
* 方法中设置的任何值。
* Sets the time limit for which threads may remain idle before
* being terminated. If there are more than the core number of
* threads currently in the pool, after waiting this amount of
* time without processing a task, excess threads will be
* terminated. This overrides any value set in the constructor.
*
* @param time the time to wait. A time value of zero will cause
* excess threads to terminate immediately after executing tasks.
* @param unit the time unit of the {@code time} argument
* @throws IllegalArgumentException if {@code time} less than zero or
* if {@code time} is zero and {@code allowsCoreThreadTimeOut}
* @see #getKeepAliveTime(TimeUnit)
*/
public void setKeepAliveTime(long time, TimeUnit unit) {
if (time < 0)
throw new IllegalArgumentException();
if (time == 0 && allowsCoreThreadTimeOut())
throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
long keepAliveTime = unit.toNanos(time);
long delta = keepAliveTime - this.keepAliveTime;
this.keepAliveTime = keepAliveTime;
if (delta < 0)
interruptIdleWorkers();
}
/**
* 返回线程保持活动的时间,该时间就是超过核心池大小的线程可以在终止前保持空闲的时间值。
* Returns the thread keep-alive time, which is the amount of time
* that threads in excess of the core pool size may remain
* idle before being terminated.
*
* @param unit the desired time unit of the result
* @return the time limit
* @see #setKeepAliveTime(long, TimeUnit)
*/
public long getKeepAliveTime(TimeUnit unit) {
return unit.convert(keepAliveTime, TimeUnit.NANOSECONDS);
}
/* User-level queue utilities */
/**
* 返回此执行程序使用的任务队列。对任务队列的访问主要用于调试和监控。
* 此队列可能正处于活动使用状态中。获取任务队列不妨碍已加入队列的任务的执行。
* Returns the task queue used by this executor. Access to the
* task queue is intended primarily for debugging and monitoring.
* This queue may be in active use. Retrieving the task queue
* does not prevent queued tasks from executing.
*
* @return the task queue
*/
public BlockingQueue<Runnable> getQueue() {
return workQueue;
}
/**
* Removes this task from the executor's internal queue if it is
* present, thus causing it not to be run if it has not already
* started.
*
* 此方法可用作取消方案的一部分。它可能无法移除在放置到内部队列之前已经转换为其他形式的任务。
* 例如,使用 submit 输入的任务可能被转换为维护 Future 状态的形式。但是,在此情况下,purge()
* 方法可用于移除那些已被取消的 Future。
* <p>This method may be useful as one part of a cancellation
* scheme. It may fail to remove tasks that have been converted
* into other forms before being placed on the internal queue. For
* example, a task entered using {@code submit} might be
* converted into a form that maintains {@code Future} status.
* However, in such cases, method {@link #purge} may be used to
* remove those Futures that have been cancelled.
*
* @param task the task to remove
* @return {@code true} if the task was removed
*/
public boolean remove(Runnable task) {
boolean removed = workQueue.remove(task);
// 如果线程A在等待队列中等待任务,线程B往队列中添加了一个任务,在线程B调用signal()方法之前,线程C
// 关闭了当前线程池,然后中断了线程A,线程A被中断后会 清除中断状态,并抛出中断异常,然后异常被getTask()
// 方法捕获了,然后判断队列不为空,不会立即返回null,而是去获取任务,如果这时把任务移除了,会导致线程又
// 进入等待队列进行等待,因此移除任务后需要调用 tryTerminate(),在线程池已关闭并且队列为空的情况下,
// 唤醒空闲的线程
tryTerminate(); // In case SHUTDOWN and now empty 避免线程池关闭,并且现在队列为空,场景如上。
return removed;
}
/**
* Tries to remove from the work queue all {@link Future}
* tasks that have been cancelled. This method can be useful as a
* storage reclamation operation, that has no other impact on
* functionality. Cancelled tasks are never executed, but may
* accumulate in work queues until worker threads can actively
* remove them. Invoking this method instead tries to remove them now.
* However, this method may fail to remove tasks in
* the presence of interference by other threads.
*/
public void purge() {
final BlockingQueue<Runnable> q = workQueue;
try {
Iterator<Runnable> it = q.iterator();
while (it.hasNext()) {
Runnable r = it.next();
if (r instanceof Future<?> && ((Future<?>)r).isCancelled())
it.remove();
}
} catch (ConcurrentModificationException fallThrough) {
// Take slow path if we encounter interference during traversal.
// Make copy for traversal and call remove for cancelled entries.
// The slow path is more likely to be O(N*N).
for (Object r : q.toArray())
if (r instanceof Future<?> && ((Future<?>)r).isCancelled())
q.remove(r);
}
tryTerminate(); // In case SHUTDOWN and now empty
}
/* Statistics */
/**
* 返回池中的当前线程数。
* Returns the current number of threads in the pool.
*
* @return the number of threads
*/
public int getPoolSize() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// 不能使用workerCountOf(ctl.get()),因为添加worker,是把 workerCount的计数
// 增加后,再获取锁,然后往 workers中添加 worker。因此 workers.size() 和 workerCount在
// 短时间内会不一致。
// 删除isTerminated() && getPoolSize() > 0的罕见和令人惊讶的可能性 (原因如上)
// Remove rare and surprising possibility of
// isTerminated() && getPoolSize() > 0
return runStateAtLeast(ctl.get(), TIDYING) ? 0
: workers.size();
} finally {
mainLock.unlock();
}
}
/**
* 返回正在执行任务的近似线程数。
* Returns the approximate number of threads that are actively
* executing tasks.
*
* @return the number of threads
*/
public int getActiveCount() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
int n = 0;
for (Worker w : workers)
// 判断是否被锁定,线程执行任务的时候会获取锁,表示其处于忙碌状态
if (w.isLocked())
++n;
return n;
} finally {
mainLock.unlock();
}
}
/**
* 返回曾经同时位于池中的最大线程数。
* Returns the largest number of threads that have ever
* simultaneously been in the pool.
*
* @return the number of threads
*/
public int getLargestPoolSize() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
return largestPoolSize;
} finally {
mainLock.unlock();
}
}
/**
* 返回曾计划执行的近似任务总数。因为在计算期间任务和线程的状态可能动态改变,所以返回值只是一个近似值。
* Returns the approximate total number of tasks that have ever been
* scheduled for execution. Because the states of tasks and
* threads may change dynamically during computation, the returned
* value is only an approximation.
*
* @return the number of tasks
*/
public long getTaskCount() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
long n = completedTaskCount;
for (Worker w : workers) {
n += w.completedTasks;
// completedTasks是任务执行完成/执行失败了才会增加,而且也不存在队列中,所以如果
// 这个线程正在执行任务,那么把这个正在执行的任务也算上
if (w.isLocked())
++n;
}
// 加上队列中的任务数
return n + workQueue.size();
} finally {
mainLock.unlock();
}
}
/**
* 返回已完成执行的近似任务总数。因为在计算期间任务和线程的状态可能动态改变,
* 所以返回值只是一个近似值,但是该值在整个连续调用过程中不会减少。
* Returns the approximate total number of tasks that have
* completed execution. Because the states of tasks and threads
* may change dynamically during computation, the returned value
* is only an approximation, but one that does not ever decrease
* across successive calls.
*
* @return the number of tasks
*/
public long getCompletedTaskCount() {
final ReentrantLock mainLock = this.mainLock;
// completedTaskCount 的更新也需要获取mainLock锁,因此不会重复统计
// 刚要退出的线程的完成任务数
mainLock.lock();
try {
// 已退出的线程的完成任务数统计到 completedTaskCount 中
long n = completedTaskCount;
// 加上未退出的线程的完成任务数
for (Worker w : workers)
n += w.completedTasks;
return n;
} finally {
mainLock.unlock();
}
}
/**
* Returns a string identifying this pool, as well as its state,
* including indications of run state and estimated worker and
* task counts.
*
* @return a string identifying this pool, as well as its state
*/
public String toString() {
long ncompleted;
int nworkers, nactive;
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
ncompleted = completedTaskCount;
nactive = 0;
nworkers = workers.size();
for (Worker w : workers) {
ncompleted += w.completedTasks;
if (w.isLocked())
++nactive;
}
} finally {
mainLock.unlock();
}
int c = ctl.get();
String rs = (runStateLessThan(c, SHUTDOWN) ? "Running" :
(runStateAtLeast(c, TERMINATED) ? "Terminated" :
"Shutting down"));
return super.toString() +
"[" + rs +
", pool size = " + nworkers +
", active threads = " + nactive +
", queued tasks = " + workQueue.size() +
", completed tasks = " + ncompleted +
"]";
}
/* Extension hooks */
/**
* 在给定的线程中执行给定的 Runnable 之前调用的方法。
* Method invoked prior to executing the given Runnable in the
* 此方法由将执行任务 r 的线程 t 调用,并且可用于重新初始化 ThreadLocals 或者执行日志记录。
* given thread. This method is invoked by thread {@code t} that
* will execute task {@code r}, and may be used to re-initialize
* ThreadLocals, or to perform logging.
*
* 此实现不执行任何操作,但可在子类中定制。注:为了正确嵌套多个重写操作,此方法结束时,
* 子类通常应该调用 super.beforeExecute。 A 继承 B, B继承 ThreadPoolExecutor,A和B都重写了这个方法,
* 那么应该在方法的最后执行super.beforeExecute(),这样才能调用上一级父类的方法
* <p>This implementation does nothing, but may be customized in
* subclasses. Note: To properly nest multiple overridings, subclasses
* should generally invoke {@code super.beforeExecute} at the end of
* this method.
*
* @param t the thread that will run task {@code r}
* @param r the task that will be executed
*/
protected void beforeExecute(Thread t, Runnable r) { }
/**
* 基于完成执行给定 Runnable 所调用的方法。此方法由执行任务的线程调用。
* Method invoked upon completion of execution of the given Runnable.
* This method is invoked by the thread that executed the task. If
* 如果非 null,则 Throwable 是导致执行突然终止的未捕获 RuntimeException 或 Error。
* non-null, the Throwable is the uncaught {@code RuntimeException}
* or {@code Error} that caused execution to terminate abruptly.
*
* 此实现不执行任何操作,但可在子类中定制。注:为了正确嵌套多个重写操作,此方法开始时,
* 子类通常应该调用 super.afterExecute。
* <p>This implementation does nothing, but may be customized in
* subclasses. Note: To properly nest multiple overridings, subclasses
* should generally invoke {@code super.afterExecute} at the
* beginning of this method. (方法开始时调用 super.afterExecute)
*
* 注:当操作显示地或者通过 submit 之类的方法包含在任务内时(如 FutureTask),
* 这些任务对象捕获和维护计算异常,因此它们不会导致突然终止,内部异常不会 传递给此方法。
* <p><b>Note:</b> When actions are enclosed in tasks (such as
* {@link FutureTask}) either explicitly or via methods such as
* {@code submit}, these task objects catch and maintain
* computational exceptions, and so they do not cause abrupt
* termination, and the internal exceptions are <em>not</em>
* passed to this method.
* 如果你想在这个方法中捕获这两种失败,你可以进一步探查这种情况,比如在这个例子子类中,
* 如果一个任务被中止,它会打印直接原因或底层异常:
* If you would like to trap both kinds of
* failures in this method, you can further probe for such cases,
* as in this sample subclass that prints either the direct cause
* or the underlying exception if a task has been aborted:
*
* <pre> {@code
* class ExtendedExecutor extends ThreadPoolExecutor {
* // ...
* protected void afterExecute(Runnable r, Throwable t) {
* super.afterExecute(r, t);
* if (t == null && r instanceof Future<?>) {
* try {
* Object result = ((Future<?>) r).get();
* } catch (CancellationException ce) {
* t = ce;
* } catch (ExecutionException ee) {
* t = ee.getCause();
* } catch (InterruptedException ie) {
* Thread.currentThread().interrupt(); // ignore/reset
* }
* }
* if (t != null)
* System.out.println(t);
* }
* }}</pre>
*
* @param r the runnable that has completed
* @param t the exception that caused termination, or null if
* execution completed normally
*/
protected void afterExecute(Runnable r, Throwable t) { }
/**
* 当 Executor 已经终止时调用的方法。默认实现不执行任何操作。
* 注:为了正确嵌套多个重写操作,子类通常应该在此方法中调用 super.terminated。
* Method invoked when the Executor has terminated. Default
* implementation does nothing. Note: To properly nest multiple
* overridings, subclasses should generally invoke
* {@code super.terminated} within this method.
*/
// 默认方法实现是空的,用于子类扩展
protected void terminated() { }
/* Predefined RejectedExecutionHandlers */
/**
* 拒绝任务处理器,直接在调用 execute()方法的线程中执行拒绝的任务,
* 除非线程被关闭,在这种情况下任务被丢弃。
* A handler for rejected tasks that runs the rejected task
* directly in the calling thread of the {@code execute} method,
* unless the executor has been shut down, in which case the task
* is discarded.
*/
public static class CallerRunsPolicy implements RejectedExecutionHandler {
/**
* Creates a {@code CallerRunsPolicy}.
*/
public CallerRunsPolicy() { }
/**
* 在调用线程中执行任务,除非线程池被关闭,在这种情况下任务被丢弃。
* Executes task r in the caller's thread, unless the executor
* has been shut down, in which case the task is discarded.
*
* @param r the runnable task requested to be executed
* @param e the executor attempting to execute this task
*/
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
// 如果线程池没有被关闭,那么使用调用execute()方法的线程执行任务
if (!e.isShutdown()) {
r.run();
}
}
}
/**
* 拒绝任务处理器,抛出 RejectedExecutionException
* A handler for rejected tasks that throws a
* {@code RejectedExecutionException}.
*/
// 默认使用的 拒绝处理器
public static class AbortPolicy implements RejectedExecutionHandler {
/**
* Creates an {@code AbortPolicy}.
*/
public AbortPolicy() { }
/**
* 总是抛出RejectedExecutionException
* Always throws RejectedExecutionException.
*
* @param r the runnable task requested to be executed
* @param e the executor attempting to execute this task
* @throws RejectedExecutionException always
*/
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
throw new RejectedExecutionException("Task " + r.toString() +
" rejected from " +
e.toString());
}
}
/**
* 拒绝任务处理器,它无声地丢弃被拒绝的任务。
* A handler for rejected tasks that silently discards the
* rejected task.
*/
public static class DiscardPolicy implements RejectedExecutionHandler {
/**
* Creates a {@code DiscardPolicy}.
*/
public DiscardPolicy() { }
/**
* 不执行任何操作,其效果是丢弃任务r。
* Does nothing, which has the effect of discarding task r.
*
* @param r the runnable task requested to be executed
* @param e the executor attempting to execute this task
*/
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
}
}
/**
* 拒绝任务处理器,丢弃最早的未处理的请求,然后重试execute(),除非线程池被
* 关闭,在这种情况下任务被丢弃。
* A handler for rejected tasks that discards the oldest unhandled
* request and then retries {@code execute}, unless the executor
* is shut down, in which case the task is discarded.
*/
public static class DiscardOldestPolicy implements RejectedExecutionHandler {
/**
* Creates a {@code DiscardOldestPolicy} for the given executor.
*/
public DiscardOldestPolicy() { }
/**
* 获取并忽略执行程序将执行的下一个任务(如果其中一个任务立即可用),
* 然后重新尝试执行任务r,除非执行程序关闭,在这种情况下,任务r将被丢弃。
* Obtains and ignores the next task that the executor
* would otherwise execute, if one is immediately available,
* and then retries execution of task r, unless the executor
* is shut down, in which case task r is instead discarded.
*
* @param r the runnable task requested to be executed
* @param e the executor attempting to execute this task
*/
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
// 如果线程池未关闭
if (!e.isShutdown()) {
// 获取第一个任务,并丢弃。如果队列为空,返回null
e.getQueue().poll();
// 重新执行任务r。如果任务被拒绝还会调用到这里... 直到成功 / 线程池被关闭为止
e.execute(r);
}
}
}
}