SpringBoot 线程池
-
- 简介
- 使用
-
- 开启
- 配置
- 使用
- SpringBoot 默认线程池
- @Async自定义线程池
- 扩展
-
- ThreadPoolTaskScheduler和ThreadPoolTaskExecutor
-
- 继承关系结构
- Reject策略预定义
- 总结
简介 程序、线程和线程池
进程是资源分配最小单位,线程是程序执行的最小单位。 计算机在执行程序时,会为程序创建相应的进程,进行资源分配时,是以进程为单位进行相应的分配。每个进程都有相应的线程,在执行程序时,实际上是执行相应的一系列线程。
总结:进程是资源分配最小单位,线程是程序执行的最小单位
使用 开启
添加注解@EnableAsync两个位置
- Service层添加注解@EnableAsync
- Application启动类添加注解@EnableAsync
下面两种配置方式
@EnableAsync
@Configuration
public class ThreadPoolConfig {@Bean(name = AsyncExecutionAspectSupport.DEFAULT_TASK_EXECUTOR_BEAN_NAME)
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//核心线程池大小
executor.setCorePoolSize(10);
//最大线程数
executor.setMaxPoolSize(30);
//队列容量
executor.setQueueCapacity(100);
//活跃时间
executor.setKeepAliveSeconds(60);
//线程名字前缀
executor.setThreadNamePrefix("taskExecutor-");
// 设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean
executor.setWaitForTasksToCompleteOnShutdown(true);
// 线程池对拒绝任务的处理策略,当线程池没有处理能力的时候,该策略会直接在 execute 方法的调用线程中运行被拒绝的任务;如果执行程序已关闭,则会丢弃该任务
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}@Bean("taskExecutor")
public Executor taskExecutor() {
// 创建一个线程池对象
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
// 定义一个线程池大小
scheduler.setPoolSize(100);
// 线程池名的前缀
scheduler.setThreadNamePrefix("taskExecutor-");
// 设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean
scheduler.setWaitForTasksToCompleteOnShutdown(true);
// 设置线程池中任务的等待时间,如果超过这个时候还没有销毁就强制销毁,以确保应用最后能够被关闭,而不是阻塞住
scheduler.setAwaitTerminationSeconds(60);
// 线程池对拒绝任务的处理策略,当线程池没有处理能力的时候,该策略会直接在 execute 方法的调用线程中运行被拒绝的任务;如果执行程序已关闭,则会丢弃该任务
scheduler.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return scheduler;
}}
使用
使用自定义的需要声明@Async的name值,不推介使用SpringBoot默认的线程池
@EnableAsync
@Service
public class TaskServiceImpl implements TaskService {
@Async("taskExecutor")
public void callback(String param){
do everything whant you want ;
}
}
它声明这样的五个方法:
- cancel方法用来取消任务,如果取消任务成功则返回true,如果取消任务失败则返回false。参数mayInterruptIfRunning表示是否允许取消正在执行却没有执行完毕的任务,如果设置true,则表示可以取消正在执行过程中的任务。如果任务已经完成,则无论mayInterruptIfRunning为true还是false,此方法肯定返回false,即如果取消已经完成的任务会返回false;如果任务正在执行,若mayInterruptIfRunning设置为true,则返回true,若mayInterruptIfRunning设置为false,则返回false;如果任务还没有执行,则无论mayInterruptIfRunning为true还是false,肯定返回true。
- isCancelled方法表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true。
- isDone方法表示任务是否已经完成,若任务完成,则返回true;
- get()方法用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回;
- get(long timeout, TimeUnit unit)用来获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null。
- 判断任务是否完成;
- 能够中断任务;
- 能够获取任务执行结果。
【JAVA|SpringBoot 线程池】@Async不声明name
@Async自定义线程池
自定义线程池的三种方式
- 重新实现接口AsyncConfigurer
- 继承AsyncConfigurerSupport
- 配置由自定义的TaskExecutor替代内置的任务执行器
继承关系结构图:
- 蓝色实现的箭头是指继承关系
- 绿色虚线指的是接口实现关系
- 绿色实线指的是接口继承关系
- ThreadPoolTaskExecutor
文章图片
- ThreadPoolTaskScheduler
文章图片
Reject策略预定义
RejectedExecutionHandler handler,Reject策略预定义有四种:
(1)ThreadPoolExecutor.AbortPolicy策略,是默认的策略,处理程序遭到拒绝将抛出运行时 RejectedExecutionException。
(2)ThreadPoolExecutor.CallerRunsPolicy策略 ,调用者的线程会执行该任务,如果执行器已关闭,则丢弃.
(3)ThreadPoolExecutor.DiscardPolicy策略,不能执行的任务将被丢弃.
(4)ThreadPoolExecutor.DiscardOldestPolicy策略,如果执行程序尚未关闭,则位于工作队列头部的任务将被删除,然后重试执行程序(如果再次失败,则重复此过程)
总结
从结构上看,两者只相差了一个TaskScheduler,而TaskScheduler是专门用于调度任务的类,这也从根本上区分了两者的用途
ThreadPoolTaskExecutor是一个专门用于执行任务的类。
ThreadPoolTaskScheduler是一个专门用于调度任务的类。
从使用上看,ThreadPoolTaskExecutor可以进行更为细粒度的划分
因此,在两者之间进行选择归结为以下问题:我是否需要执行或安排任务的执行
参考:
https://blog.csdn.net/andybegin/article/details/110002100
https://www.cnblogs.com/wlandwl/p/async.html
https://blog.csdn.net/qq_43253123/article/details/82983810
https://www.jianshu.com/p/0a96c542f42d
推荐阅读
- java|Java 应用线上问题排查思路、常用工具小结
- spring|Java 微服务的QPS上不去(试试这些办法)
- java|java gc日志乱码_让bug无处藏身,Java 线上问题排查思路、常用工具
- java|java gc日志乱码_让 Bug 无处藏身,Java 线上问题排查思路、常用工具
- java|基于配置中心的轻量级动态可监控线程池 - DynamicTp
- spring|java性能优化,产品的 QPS 翻倍了
- java|线程池如何观测(这个方案让你对线程池的运行情况了如指掌)
- 定位|Spring Boot 接口频繁超时,Alibaba 开源 Arthas 精准定位 BUG 问题!
- 源程序|SpringBoot框架入门(二)