线程池配置
线程池配置
基础配置
/**
* 用给定的初始参数创建一个新的ThreadPoolExecutor。
*/
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;
}
Spring配置
实际在initialize()方法中初始化了基础配置的ThreadPoolExecutor对象
@Configuration
public class TaskConfig {
@Bean("taskModuleExecutor")
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setCorePoolSize(64);// 核心线程数
threadPoolTaskExecutor.setMaxPoolSize(200);// 最大线程数
threadPoolTaskExecutor.setQueueCapacity(1000);// 队列最大长度
threadPoolTaskExecutor.setKeepAliveSeconds(60);// 线程池维护线程所允许的空闲时间,默认为60s
threadPoolTaskExecutor.setThreadNamePrefix("task-concurrent-work");
threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
}
}
7大重要参数
这里使用基础配置的参数
-
corePoolSize
:核心线程数。线程池中常驻线程数量,线程池初始化时是默认是没有线程的,当有需要执行的任务来时才会创建。任务提交到线程池,线程数量尚未达到corePoolSize时候,任务不加入队列直接创建核心线程执行,线程的数量随着任务的增加而增加。 -
workQueue
:队列。随着任务的增多,核心线程不能消化后,则将任务放入到任务队列中,等待核心线程执行,此时线程池中的线程数量不变,依然是核心线程数阻塞队列 说明 ArrayBlockingQueue 是一个数组实现的有界队列,初始化是必须设置大小 LinkedBlockingQueue 基于链表实现的队列,初始化大小则是有界队列,否则是无界队列 PriorityBlockingQueue 优先级无限队列 DelayQueue 无界延迟队列 SynchronizedQueue 同步队列,不存储元素,插入操作必须等另一个线程执行移除操作,否则阻塞 -
maximumPoolSize
:最大线程数。当任务队列满了以后,线程数量小于最大线程数,则创建非核心线程去消费。(为什么要等队列满了以后才创建呢?这个主要是因为创建线程和销毁线程是一个高成本操作,所以尽量使用常驻线程来处理任务) -
handler
:饱和策略。当线程数量达到最大线程数量以后,同时队列满则执行饱和策略拒绝策略 说明 AbordPolicy 抛出 RejectedExecutionException
来拒绝新任务的处理DiscrdPolicy 不处理新任务,直接丢弃掉,不抛异常 DiscardOldestPolicy 此策略将丢弃最早的未处理的任务请求 CallerRundsPolicy 调用执行自己的线程运行任务,也就是直接在调用 execute
方法的线程中运行(run
)被拒绝的任务,如果执行程序已关闭,则会丢弃该任务。因此这种策略会降低对于新任务提交速度,影响程序的整体性能。如果您的应用程序可以承受此延迟并且你要求任何一个任务请求都要被执行的话,你可以选择这个策略自定义策略 -
keepAliveTime
:非核心线程的空闲时间、单位。非核心线程在keepAliveTime时间内等待获取任务,超过keepAliveTime则执行销毁线程。非核心线程销毁后,线程池中的线程数量就只剩下核心线程,核心线程正常情况下就不再被销毁 -
unit
:非核心线程的空闲时间的单位。 -
threadFactory
: 用于创建线程的工厂。