SpringBoot实现线程池
现在由于系统越来越复杂,导致很多接口速度变慢,这时候就会想到可以利用线程池来处理一些耗时并不影响系统的操作。
新建Spring Boot项目
1. ExecutorConfig.xml
【SpringBoot实现线程池】新建线程池配置文件。
@Configuration@EnableAsyncpublic class ExecutorConfig {private static final Logger logger = LoggerFactory.getLogger(ExecutorConfig.class); @Value("${async.executor.thread.core_pool_size}")private int corePoolSize; @Value("${async.executor.thread.max_pool_size}")private int maxPoolSize; @Value("${async.executor.thread.queue_capacity}")private int queueCapacity; @Value("${async.executor.thread.name.prefix}")private String namePrefix; @Bean(name = "asyncServiceExecutor")public Executor asyncServiceExecutor() {logger.info("start asyncServiceExecutor"); ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //配置核心线程数executor.setCorePoolSize(corePoolSize); //配置最大线程数executor.setMaxPoolSize(maxPoolSize); //配置队列大小executor.setQueueCapacity(queueCapacity); //配置线程池中的线程的名称前缀executor.setThreadNamePrefix(namePrefix); // rejection-policy:当pool已经达到max size的时候,如何处理新任务// CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); //执行初始化executor.initialize(); return executor; }}
2. application.yml
@Value配置在application.yml,可以参考配置
# 异步线程配置async:executor:thread:# 配置核心线程数core_pool_size: 10# 配置最大线程数max_pool_size: 20# 配置队列大小queue_capacity: 99999# 配置线程池中的线程的名称前缀name:prefix: async-service-
3. AsyncService.java
创建一个 Service 接口,是异步线程的接口,将方法写入其实现类即可
public interface AsyncService {/** * 执行异步任务的方法,参数自己可以添加*/void executeAsync(); }
4. AsyncServiceImpl.java
实现类,用来写业务逻辑
@Servicepublic class AsyncServiceImpl implements AsyncService {private static final Logger logger = LoggerFactory.getLogger(AsyncServiceImpl.class); @Override@Async("asyncServiceExecutor")public void executeAsync() {logger.info("start executeAsync"); System.out.println("异步线程执行开始了"); System.out.println("可以将耗时的操作放到这里执行了"); logger.info("end executeAsync"); }}
++将 Service 层的服务异步化,在executeAsync()方法上增加注解@Async("asyncServiceExecutor"),asyncServiceExecutor方法是前面ExecutorConfig.java中的方法名,表明executeAsync方法进入的线程池是asyncServiceExecutor方法创建的。++
5. AsyncController.java
在控制器里面注入AsyncService,调用其中的方法即可
@Autowiredprivate AsyncService asyncService; @GetMapping("/async")public void async(){asyncService.executeAsync(); }
6. 用Postman进行测试
打印log入下
2021-06-16 22:15:47.655INFO 10516 --- [async-service-5] c.u.d.e.executor.impl.AsyncServiceImpl: start executeAsync5. 将当前线程池的运行状况打印出来
异步线程执行开始了
可以将耗时的操作放到这里执行了
2021-06-16 22:15:47.655INFO 10516 --- [async-service-5] c.u.d.e.executor.impl.AsyncServiceImpl: end executeAsync
2021-06-16 22:15:47.770INFO 10516 --- [async-service-1] c.u.d.e.executor.impl.AsyncServiceImpl: start executeAsync
异步线程执行开始了
可以将耗时的操作放到这里执行了
2021-06-16 22:15:47.770INFO 10516 --- [async-service-1] c.u.d.e.executor.impl.AsyncServiceImpl: end executeAsync
2021-06-16 22:15:47.816INFO 10516 --- [async-service-2] c.u.d.e.executor.impl.AsyncServiceImpl: start executeAsync
异步线程执行开始了
可以将耗时的操作放到这里执行了
2021-06-16 22:15:47.816INFO 10516 --- [async-service-2] c.u.d.e.executor.impl.AsyncServiceImpl: end executeAsync
2021-06-16 22:15:48.833INFO 10516 --- [async-service-3] c.u.d.e.executor.impl.AsyncServiceImpl: start executeAsync
异步线程执行开始了
可以将耗时的操作放到这里执行了
2021-06-16 22:15:48.834INFO 10516 --- [async-service-3] c.u.d.e.executor.impl.AsyncServiceImpl: end executeAsync
2021-06-16 22:15:48.986INFO 10516 --- [async-service-4] c.u.d.e.executor.impl.AsyncServiceImpl: start executeAsync
异步线程执行开始了
可以将耗时的操作放到这里执行了
2021-06-16 22:15:48.987INFO 10516 --- [async-service-4] c.u.d.e.executor.impl.AsyncServiceImpl: end executeAsync
至此简单的线程池已经实现了。
5.1 VisiableThreadPoolTaskExecutor.java
public class VisiableThreadPoolTaskExecutor extends ThreadPoolTaskExecutor {private static final Logger logger = LoggerFactory.getLogger(VisiableThreadPoolTaskExecutor.class); private void showThreadPoolInfo(String prefix) {ThreadPoolExecutor threadPoolExecutor = getThreadPoolExecutor(); if (null == threadPoolExecutor) {return; }logger.info("{}, {},taskCount [{}], completedTaskCount [{}], activeCount [{}], queueSize [{}]",this.getThreadNamePrefix(),prefix,threadPoolExecutor.getTaskCount(),threadPoolExecutor.getCompletedTaskCount(),threadPoolExecutor.getActiveCount(),threadPoolExecutor.getQueue().size()); }@Overridepublic void execute(Runnable task) {showThreadPoolInfo("1. do execute"); super.execute(task); }@Overridepublic void execute(Runnable task, long startTimeout) {showThreadPoolInfo("2. do execute"); super.execute(task, startTimeout); }@Overridepublic Future> submit(Runnable task) {showThreadPoolInfo("1. do submit"); return super.submit(task); }@OverridepublicFuture submit(Callable task) {showThreadPoolInfo("2. do submit"); return super.submit(task); }@Overridepublic ListenableFuture> submitListenable(Runnable task) {showThreadPoolInfo("1. do submitListenable"); return super.submitListenable(task); }@Overridepublic ListenableFuture submitListenable(Callable task) {showThreadPoolInfo("2. do submitListenable"); return super.submitListenable(task); }}
5.2 修改asyncServiceExecutor.java
修改ExecutorConfig.java的asyncServiceExecutor方法,将ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor()改为ThreadPoolTaskExecutor executor = new VisiableThreadPoolTaskExecutor()
@Bean(name = "asyncServiceExecutor")public Executor asyncServiceExecutor() {logger.info("start asyncServiceExecutor"); //在这里修改ThreadPoolTaskExecutor executor = new VisiableThreadPoolTaskExecutor(); //配置核心线程数executor.setCorePoolSize(corePoolSize); //配置最大线程数executor.setMaxPoolSize(maxPoolSize); //配置队列大小executor.setQueueCapacity(queueCapacity); //配置线程池中的线程的名称前缀executor.setThreadNamePrefix(namePrefix); // rejection-policy:当pool已经达到max size的时候,如何处理新任务// CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); //执行初始化executor.initialize(); return executor; }
5.3 使用Postman进行测试
2021-06-16 22:23:30.951INFO 14088 --- [nio-8087-exec-2] u.d.e.e.i.VisiableThreadPoolTaskExecutor : async-service-, 2. do submit,taskCount [0], completedTaskCount [0], activeCount [0], queueSize [0]可以看到上面async-service-, 2. do submit,taskCount [3], completedTaskCount [3], activeCount [0], queueSize [0]关于线程的信息都打印出来了。
2021-06-16 22:23:30.952INFO 14088 --- [async-service-1] c.u.d.e.executor.impl.AsyncServiceImpl: start executeAsync
异步线程执行开始了
可以将耗时的操作放到这里执行了
2021-06-16 22:23:30.953INFO 14088 --- [async-service-1] c.u.d.e.executor.impl.AsyncServiceImpl: end executeAsync
2021-06-16 22:23:31.351INFO 14088 --- [nio-8087-exec-3] u.d.e.e.i.VisiableThreadPoolTaskExecutor : async-service-, 2. do submit,taskCount [1], completedTaskCount [1], activeCount [0], queueSize [0]
2021-06-16 22:23:31.353INFO 14088 --- [async-service-2] c.u.d.e.executor.impl.AsyncServiceImpl: start executeAsync
异步线程执行开始了
可以将耗时的操作放到这里执行了
2021-06-16 22:23:31.353INFO 14088 --- [async-service-2] c.u.d.e.executor.impl.AsyncServiceImpl: end executeAsync
2021-06-16 22:23:31.927INFO 14088 --- [nio-8087-exec-5] u.d.e.e.i.VisiableThreadPoolTaskExecutor : async-service-, 2. do submit,taskCount [2], completedTaskCount [2], activeCount [0], queueSize [0]
2021-06-16 22:23:31.929INFO 14088 --- [async-service-3] c.u.d.e.executor.impl.AsyncServiceImpl: start executeAsync
异步线程执行开始了
可以将耗时的操作放到这里执行了
2021-06-16 22:23:31.930INFO 14088 --- [async-service-3] c.u.d.e.executor.impl.AsyncServiceImpl: end executeAsync
2021-06-16 22:23:32.496INFO 14088 --- [nio-8087-exec-7] u.d.e.e.i.VisiableThreadPoolTaskExecutor : async-service-, 2. do submit,taskCount [3], completedTaskCount [3], activeCount [0], queueSize [0]
2021-06-16 22:23:32.498INFO 14088 --- [async-service-4] c.u.d.e.executor.impl.AsyncServiceImpl: start executeAsync
异步线程执行开始了
可以将耗时的操作放到这里执行了
2021-06-16 22:23:32.499INFO 14088 --- [async-service-4] c.u.d.e.executor.impl.AsyncServiceImpl: end executeAsync
到此这篇关于SpringBoot实现线程池的文章就介绍到这了,更多相关SpringBoot 线程池内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- Activiti(一)SpringBoot2集成Activiti6
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- MybatisPlus使用queryWrapper如何实现复杂查询
- python学习之|python学习之 实现QQ自动发送消息
- 孩子不是实现父母欲望的工具——林哈夫
- SpringBoot调用公共模块的自定义注解失效的解决
- opencv|opencv C++模板匹配的简单实现
- Node.js中readline模块实现终端输入
- 解决SpringBoot引用别的模块无法注入的问题
- java中如何实现重建二叉树