一.项目中线程池的使用:
参数配置:(application.yml配置文件中)
task:
pool:
corePoolSize: 10
maxPoolSize: 50
keepAliveSeconds: 300
queueCapacity: 1000
通过注解
@Component
@ConfigurationProperties(prefix = "spring.task.pool")
获取配置文件的参数设置:
线程池配置:
@EnableAsync
@Configuration
public class ThreadPoolConfig {
@Autowired
private ThreadPoolProperties poolConfig;
//定义线程池(同理可拓展)
@Bean
public Executor testTaskAsyncPool() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(poolConfig.getCorePoolSize());
executor.setMaxPoolSize(poolConfig.getMaxPoolSize());
executor.setQueueCapacity(poolConfig.getQueueCapacity());
executor.setKeepAliveSeconds(poolConfig.getKeepAliveSeconds());
executor.setThreadNamePrefix("testExecutor-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
参数说明:
corePoolSize:核心线程数---10
a.核心线程会一直存活,即使没有任务执行也存活
b.当线程数少于核心线程数时,即使有空闲的线程,也会优先创建新的线程去处理。
c.设置参数allowCoreThreadTimeout=true(默认false),核心线程会超时关闭。
queueCapacity:任务队列容量(阻塞队列)---1000
a.当核心线程数达到最大时,新任务会放在队列中排队等待执行。
maxPoolSize:最大线程数---50
a.当线程数大于corePoolSize时,且任务队列也已满,线程池会创建新的线程处理任务。
b.当线程数=maxPoolSize,且任务队列已满,线程池会默认抛出异常拒绝执行任务。
keepAliveSeconds:线程空闲时间---300
a.当线程空闲时间达到这个设置时间时,线程会自动退出,直到线程数量=corePoolSize
b.如果allowCoreThreadTimeout=true,则会直到线程数量=0
rejectedExecutionHandler:任务拒绝处理器
a.两种情况会拒绝处理任务
1st.当线程数量已经达到maxPoolSize,且队列已满,就会拒绝新任务
2nd.当线程池被调用shutdown后,会等线程池里任务执行完毕,再shutdown,如果在调用shutdown和线程池真正shutdown之间提交任务,会拒绝新任务。
b.线程池会调用rejectedExecutionHandler来处理任务,默认是AbortPolicy,抛出异常
c.ThreadPoolExecutor内部实现的方式:
c1.AbortPolicy 丢弃任务,抛运行时异常
c2.CallerRunsPolicy 执行任务
c3.DiscardPolicy 忽视,什么都不会发生
c4.DiscardOldestPolicy 从队列中踢出最先进入队列(最后一个执行)的任务
d.也可实现RejectedExecutionHandler接口,自定义处理器
ThreadPoolExecutor执行顺序:
1.当线程数小于核心线程数时,创建新线程
2.当线程数大于等于核心线程数时,且任务队列未满时,将任务放入任务队列
3.当线程数大于核心线程数,且任务队列已满时,
a.若线程数少于最大线程数,创建线程
b.若线程数等于最大线程数,抛出异常,拒绝任务
二.线程池的使用:
通过注解的方式使用,在方法上添加注解
@Async("testTaskAsyncPool")
可在业务代码的方法上直接调用即可。。。