/**
*
* @param corePoolSize 线程池的核心线程数,当提交一个任务时,线程池创建一个新线程执行任务,直到当前线程数等于corePollSize;
* 如果当前线程数为corePoolSize,继续提交的任务会被保存到阻塞队列中,等待被执行;
* 如果执行了线程池的prestartAllCoreThread()方法时,线程池会提前创建并启动所有的核心线程
* @param maximumPoolSize 线程池中允许的最大线程数,如果阻塞队列满了,且继续提交任务,则会创建新的线程执行任务,
* 前提时当前线程数小于maximumPollSize;
* @param keepAliveTime 线程池维护线程所允许的空闲时间,当线程池中的线程数量大于corePollSize时,如果这个时候没有新的任务提交,
* 核心线程外的线程不会立即销毁,而是会等待,直到等待时间超过的keepAliveTime;
* @param unit keepAliveTime的单位
* @param workQueue 用来保存等待被执行的任务的阻塞队列,且任务必须实现Runable接口,再jdk中提供了如下的阻塞队列:
* 1. ArrayBlockingQueue: 基于数组结构的有界阻塞队列,按FIFO排序任务
* 2. LinkedBlockingQueue: 基于链表结构的阻塞队列,按FIFO排序任务,吞吐量通常要高于ArrayBlockingQueue
* 3. SynchronousQueue: 一个不储存元素的阻塞队列,每个操作必须等到另一个线程调用移除操作,
* 否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQueue
* 4. priorityBlockingQueue: 具有优先级的无界阻塞队列
* @param threadFactory 它是ThreadFactory类型的变量,用来创建新线程,默认调用Executors.defaultThreadFactory()来创建线程,使用默认的
* ThreadFactory来创建线程时,会使新创建的线程具有先攻的NORM_PRIORITY优先级并且是非守护线程,同时也设置了线程的名称
* @param handler 线程池的饱和策略,当阻塞队列满了,且没有空闲的工作线程,如果继续提交任务,必须采取一种策略处理该任务,线程池提供了4种策略
* 1.AbortPolicy: 直接抛出异常,默认策略
* 2.CallerRunsPolicy: 用调用者所在的线程来执行任务
* 3.DiscardOldestPolicy: 丢弃阻塞队列种最靠前的任务,并执行当前任务
* 4.DiscardPolicy: 直接丢弃策略
* 以上的4种策略都是ThreadPollExecutor的内部类
* 当然也可以根据应用场景实现RejectedExecutionHandler接口,自定义饱和策略,如记录日志或持久化储存不能处理的任务
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
线程池内部是通过队列+线程实现的,当我们利用线程池执行任务时:
- 如果此时线程池中的线程数量小于corePoolSize,即使线程池种的线程都处于空闲状态,也要创建新的线程来处理被添加的任务
- 如果此时线程池中的线程数量等于corePoolSize,但是缓冲队列workQueue未满,那么任务被放入缓冲队列
- 如果此时线程池中的线程数量大于等于corePoolSize,缓冲队列已满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务
- 如果此时线程池中的线程数量大于corePoolSize,缓冲队列已满,并且线程池中的数量等于maximumPoolSize,那么通过handler所指定的策略来处理此任务
- 当线程池中的线程数量大于corePollSize,如果某线程空闲时间超过keepAliveTime,线程将被终止,这样线程池可以动态调整池中的线程数