public class ThreadPoolExecutor extends AbstractExecutorService {}
public abstract class AbstractExecutorService implements ExecutorService {}
public interface ExecutorService extends Executor {}
public interface Executor {}
* An {@link ExecutorService} that executes each submitted task using
* one of possibly several pooled threads, normally configured
* using {@link Executors} factory methods.
*
* Thread pools address two different problems:
* 1. 提升处理大量异步任务的性能
* 2. 资源,线程管理方法
*
* Executors#newCachedThreadPool (unbounded thread pool, with
* automatic thread reclamation);
* Executors#newFixedThreadPool (fixed size thread pool);
* 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:
*
* A {@code ThreadPoolExecutor} will automatically adjust the
* pool size according to the bounds set by
* corePoolSize (see {@link #getCorePoolSize}) and
* maximumPoolSize (see {@link #getMaximumPoolSize}).
*
* 1. 当提交一个任务时,如果当前处于运行状态的线程数量小于corePoolSize,就会新建一个线程来
* 处理任务,即使有其它的工作线程已经处于idle状态;
* 2. 如果当前处于运行状态的线程数量大于corePoolSize,并且无法将任务添加到queue中,
* 并且线程数量小于maximumPoolSize,也会新创建一个线程;
*
* 所以,如果设置corePoolSize和maximumPoolSize相同,就创建了一个固定大小的线程池;
* 如果设置maximumPoolSize为一个本质上无界的数比如Integer.MAX_VALUE, you allow the
* pool to accommodate an arbitrary number of concurrent tasks
* (允许池容纳任意数量的并发任务。)
*
* By default, 只有任务到来的时候,core thread才会被创建并开始,
* 但是可以通过重写{#prestartCoreThread} 或者 {#prestartAllCoreThreads}.
* You probably want to prestart threads if
* you construct the pool with a non-empty queue.
*
* New threads are created using a {@link ThreadFactory}.
* Executors#defaultThreadFactory is used for default.
* it 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, etc
*
* If the pool currently has more than corePoolSize threads,
* excess threads will be terminated if they have been idle for more
* than the keepAliveTime .
* 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. By default, the keep-alive policy
* applies only when there are more than corePoolSize threads. But
* allowCoreThreadTimeOut(boolean)也可以改变这个策略, 只要keepAliveTime不为0.
*
* Queuing
* 1. 如果小于corePoolSize数量的线程在运行,就将创建新线程,而不会入到任务列。
* 2. 如果大于corePoolSize数量的线程在运行,就将添加到队列中,而不是创建新线程。
* 3. 如果任务不能被添加到队列中,并且线程数量小于maximumPoolSize,则会创建一个新的线程。
*
* 有三种队列管理策略:
*
* 1. Direct handoffs(直接切换). A good default choice for a work
* queue is a {@link SynchronousQueue} that hands off tasks to threads
* without otherwise holding them. 如果没有可以立即使用的线程,尝试将任务入列将失败
* 此时将创建新的线程来执行任务,这一策略避免了当处理多个可能有相互依赖关系的任务时造成死机
* Direct handoffs 通常使用无界的maximumPoolSizes来避免task被rejection.
*
* 2. Unbounded queues(无界队列). 使用不指定容量的无界队列,当所有的coreThread
* 都在运行状态时,新添加的任务将添加到队列中进行等待执行的状态,所以,不会有超过
* corePoolSize数量的线程被创建。(And the value of the maximumPoolSize
* therefore doesn't have any effect.) This may be appropriate(适当) when
* each task is completely independent(独立) of others;
* While this style of queuing can be useful in smoothing out
* transient(短暂的) bursts(爆炸) of requests.
*
* 3. Bounded queues. A bounded queue {@link ArrayBlockingQueue} helps
* prevent resource exhaustion(枯竭) when used finite(有限的) maximumPoolSizes,
* but can be more difficult to tune and control.
* Queue sizes and maximumPoolsize 可以相互转换配套使用:
* 1. large queues and small pools minimizes CPU usage, OS resources, and
* context-switching overhead, but may lead to low throughput(吞吐量).
* If tasks frequently block, a system may be able to schedule
* time for more threads than you otherwise allow.
* 2. small queues with larger pool sizes, which keeps CPUs busier but
* may 遇到不可接受的调度开销,这也会降低吞吐量,也会降低吞吐量 *
* /
/**
* @param corePoolSize 一直保存在池中的线程数量,即使线程的运行状态已经是idle,
* 除非allowCoreThreadTimeOut为true
* @param maximumPoolSize 最大允许的线程数量
* @param keepAliveTime 当线程数量大于coreSize时,当线程进入idle状态后,将等待一定的时间
* 如果有新任务进入,则执行任务,否则,terminate。
* @param unit the time unit
* @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
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}