Java 线程池
参数分析
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.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
corePoolSize:核心线程数,当线程数小于该值时,线程池会优先创建新线程来执行任务,如果调用了线程池的prestartAllCoreThreads方法,线程池会提前创建并启动所有基本线程,除非设置了allowCoreThreadTimeOut,否则核心线程将持续保留在线程池中即时没有新的任务提交过来。
maximumPoolSize:最大线程数,即线程池所能允许创建的最大线程数量。
keepAliveTime:空闲线程存活时间,当线程数量大于核心线程数时,这是多余空闲线程在终止之前等待新任务的最长时间。
unit:keepAliveTime数值的时间单位。
workQueue:任务队列,用于缓存未执行的任务,队列一直会持有任务直到有线程开始执行它。
threadFactory:线程工厂,可以通过工厂创建更具识别性质的线程,如线程名字等。
handler:拒绝策略,当线程和队列都处于饱和时就使用拒绝策略来处理新任务。
线程池中线程的使用和创建规则
1、当来了新任务,如果线程池中空闲线程数量小于corePoolSize,则直接拿线程池中新的线程来处理任务;
2、如果线程池正在运行的线程数量大于等于corePoolSize,而此时workQueue队列未满,则将此任务缓存到队列中;
3、如果线程池正在运行的线程数量大于等于corePoolSize,且workQueue队列已满,但现在的线程数量还小于maximumPoolSize,则创建新的线程来执行任务。
4、如果线程数量已经大于maximumPoolSize且workQueue队列也已经满了,则使用拒绝策略来处理该任务,默认的拒绝策略就是抛出异常(AbortPolicy)。
基本运作流程。
线程池状态
RUNNING:线程池能够接受新任务,以及对新添加的任务进行处理。
SHUTDOWN:线程池不可以接受新任务,但是可以对已添加的任务进行处理。
STOP:线程池不接收新任务,不处理已添加的任务,并且会中断正在处理的任务。
TIDYING:当所有的任务已终止,ctl记录的"任务数量"为0,线程池会变为TIDYING状态。当线程池变为TIDYING状态时,会执行钩子函数terminated()。terminated()在ThreadPoolExecutor类中是空的,若用户想在线程池变为TIDYING时,进行相应的处理;可以通过重载terminated()函数来实现。
TERMINATED:线程池彻底终止的状态。