SpringBoot实现线程池
现在由于系统越来越复杂,导致很多接口速度变慢,这时候就会想到可以利用线程池来处理一些耗时并不影响系统的操作。
新建Spring Boot项目
1. ExecutorConfig.xml
新建线程池配置文件。
@Configuration
@EnableAsync
public 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
实现类,用来写业务逻辑
@Service
public 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,调用其中的方法即可
@Autowired
private AsyncService asyncService;
@GetMapping("/async")
public void async(){
asyncService.executeAsync();
}
6. 用Postman进行测试
打印log入下
2021-06-16 22:15:47.655 INFO 10516 --- [async-service-5] c.u.d.e.executor.impl.AsyncServiceImpl : start executeAsync
异步线程执行开始了
可以将耗时的操作放到这里执行了
2021-06-16 22:15:47.655 INFO 10516 --- [async-service-5] c.u.d.e.executor.impl.AsyncServiceImpl : end executeAsync
2021-06-16 22:15:47.770 INFO 10516 --- [async-service-1] c.u.d.e.executor.impl.AsyncServiceImpl : start executeAsync
异步线程执行开始了
可以将耗时的操作放到这里执行了
2021-06-16 22:15:47.770 INFO 10516 --- [async-service-1] c.u.d.e.executor.impl.AsyncServiceImpl : end executeAsync
2021-06-16 22:15:47.816 INFO 10516 --- [async-service-2] c.u.d.e.executor.impl.AsyncServiceImpl : start executeAsync
异步线程执行开始了
可以将耗时的操作放到这里执行了
2021-06-16 22:15:47.816 INFO 10516 --- [async-service-2] c.u.d.e.executor.impl.AsyncServiceImpl : end executeAsync
2021-06-16 22:15:48.833 INFO 10516 --- [async-service-3] c.u.d.e.executor.impl.AsyncServiceImpl : start executeAsync
异步线程执行开始了
可以将耗时的操作放到这里执行了
2021-06-16 22:15:48.834 INFO 10516 --- [async-service-3] c.u.d.e.executor.impl.AsyncServiceImpl : end executeAsync
2021-06-16 22:15:48.986 INFO 10516 --- [async-service-4] c.u.d.e.executor.impl.AsyncServiceImpl : start executeAsync
异步线程执行开始了
可以将耗时的操作放到这里执行了
2021-06-16 22:15:48.987 INFO 10516 --- [async-service-4] c.u.d.e.executor.impl.AsyncServiceImpl : end executeAsync
至此简单的线程池已经实现了。
5. 将当前线程池的运行状况打印出来
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());
}
@Override
public void execute(Runnable task) {
showThreadPoolInfo("1. do execute");
super.execute(task);
}
@Override
public void execute(Runnable task, long startTimeout) {
showThreadPoolInfo("2. do execute");
super.execute(task, startTimeout);
}
@Override
public Future<?> submit(Runnable task) {
showThreadPoolInfo("1. do submit");
return super.submit(task);
}
@Override
public <T> Future<T> submit(Callable<T> task) {
showThreadPoolInfo("2. do submit");
return super.submit(task);
}
@Override
public ListenableFuture<?> submitListenable(Runnable task) {
showThreadPoolInfo("1. do submitListenable");
return super.submitListenable(task);
}
@Override
public <T> ListenableFuture<T> submitListenable(Callable<T> 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.951 INFO 14088 --- [nio-8087-exec-2] u.d.e.e.i.VisiableThreadPoolTaskExecutor : async-service-, 2. do submit,taskCount [0], completedTaskCount [0], activeCount [0], queueSize [0]
2021-06-16 22:23:30.952 INFO 14088 --- [async-service-1] c.u.d.e.executor.impl.AsyncServiceImpl : start executeAsync
异步线程执行开始了
可以将耗时的操作放到这里执行了
2021-06-16 22:23:30.953 INFO 14088 --- [async-service-1] c.u.d.e.executor.impl.AsyncServiceImpl : end executeAsync
2021-06-16 22:23:31.351 INFO 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.353 INFO 14088 --- [async-service-2] c.u.d.e.executor.impl.AsyncServiceImpl : start executeAsync
异步线程执行开始了
可以将耗时的操作放到这里执行了
2021-06-16 22:23:31.353 INFO 14088 --- [async-service-2] c.u.d.e.executor.impl.AsyncServiceImpl : end executeAsync
2021-06-16 22:23:31.927 INFO 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.929 INFO 14088 --- [async-service-3] c.u.d.e.executor.impl.AsyncServiceImpl : start executeAsync
异步线程执行开始了
可以将耗时的操作放到这里执行了
2021-06-16 22:23:31.930 INFO 14088 --- [async-service-3] c.u.d.e.executor.impl.AsyncServiceImpl : end executeAsync
2021-06-16 22:23:32.496 INFO 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.498 INFO 14088 --- [async-service-4] c.u.d.e.executor.impl.AsyncServiceImpl : start executeAsync
异步线程执行开始了
可以将耗时的操作放到这里执行了
2021-06-16 22:23:32.499 INFO 14088 --- [async-service-4] c.u.d.e.executor.impl.AsyncServiceImpl : end executeAsync
可以看到上面async-service-, 2. do submit,taskCount [3], completedTaskCount [3], activeCount [0], queueSize [0]关于线程的信息都打印出来了。
到此这篇关于SpringBoot实现线程池的文章就介绍到这了,更多相关SpringBoot 线程池内容请搜索无名以前的文章或继续浏览下面的相关文章希望大家以后多多支持无名!
同类资源
- MySqlPool,MySql线程池
易语言MySqlPool2.0例子源代码,2.0这个基于zyJson写了。...
- Java基于springboot教务管理系统
Java基于springboot教务管理系统本文件感兴趣的可以参考一下,帮助学校管理教务系统,用一个帐号解决学校教务...
- springBootNoMaven实现定时任务功能
springBootNoMaven本文件感兴趣的可以参考一下,不使用maven环境,创建springboot项目,实现了定时任务功能简单...
- 线程池自动拨号,HP实现同步异步混发通讯
易语言线程池自动拨号,HP实现同步异步混发通讯例子源代码,发现有些人还是对多线程拨号,HP的一些操作不太懂。...
- 优易多线程池模块
易语言优易多线程池模块例子,添加模块应用后直接可以查看具体的使用方法了,在线程处理程序后面必加。...
- E-APPLE线程池模块
易语言E-APPLE线程池模块例子,添加模块应用后直接可以查看具体的使用方法了,使用本线程池前请先建立一个变...
- IOCP线程池模块支持多个池同时运行
易语言IOCP线程池模块支持多个池同时运行例子,添加模块应用后直接可以查看具体的使用方法了,使用的方法和精...
- 超级简化线程池,支持库操作,dll操作两种方式
易语言超级简化线程池,支持库操作,dll操作两种方式例子源代码,编译好直接使用建议用dll的方式。...
- 线程池多参带返回值,传自定义传任意类型
易语言线程池多参带返回值,传自定义传任意类型例子源代码,线程池可以多参还能带返回值,使用简单到你不敢相信...
- 线程池多线程队列
易语言线程池多线程队列例子源代码,翻了一下自己的源码好像并没有什么值钱的东西。...
- N+线程池,多线程带进度回调
易语言N+线程池,多线程带进度回调例子源代码,修复内存泄漏问题。...
- 鱼刺多线程,线程池简单实用
易语言鱼刺多线程,线程池简单实用例子源代码,请输入并发线程数。...