概述
springboot2.x+自定义线程池实现异步查询并返回结果集
- 需求概述
- 示例代码
- 入口类
- 自定义线程池组件
- controller层
- Service层
- 总结
需求概述
在基于springboot开发web项目过程中,有这么一个接口需求:要统计各省推送的河流、湖泊、水库等要素的总数,因为各要素保存在单独的表中,统计各表的业务互不影响,为提升统计效率考虑使用springboot的@Asyn异步多线程调用,因为各业务都有返回数据需要处理,这个时候就需要使用Fucture类来封装返回值,并在controller层作相应处理。话不多说,直接上代码:
示例代码
入口类
在工程主类添加@EnableAsync注解开启sprngboot异步执行功能。
@SpringBootApplication
@EnableAsync
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
自定义线程池组件
/**
* @Deacription 异步线程池配置类
* @Author wenyt
* @Date 2021/3/4 10:25
* @Version 1.0
**/
@Configuration
public class TaskPoolConfiguration {
@Bean("taskExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//线程池维护线程的最少数量
executor.setCorePoolSize(20);
//最大线程数
executor.setMaxPoolSize(25);
//队列大小
executor.setQueueCapacity(200);
//允许的空闲时间
executor.setKeepAliveSeconds(60);
//线程名称前缀
executor.setThreadNamePrefix("executor-");
//对拒绝task的处理策略(默认)
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//优雅关闭线程池
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(60);
return executor;
}
}
controller层
为了简化示例代码,将异步返回结果归集业务逻辑写到了controller层,实际开发过程中建议将此逻辑写到service层,异步查询逻辑写到单独定义的异步组件中
@RestController
@RequestMapping("/el")
public class ElController {
@Autowired
private ElService elService;
@GetMapping(value = "/")
public ResponseJSONResult getElPushCount(@RequestParam(value = "elTypes") String elTypes) throws InterruptedException {
List<String> elTypeList = Arrays.asList(elTypes.split(","));
//定义返回集合
List<ElPushCount> elPushCounts = new ArrayList<>();
List<Future<List<ElPushCount>>> futures = new ArrayList<>();
//多线程执行任务,每个任务返回一个Future入futures
for (String elType : elTypeList) {
final Future<List<ElPushCount>> future = elService.getElPushCountByElType(elType);
futures.add(future);
}
//结果归集,用迭代器遍历futureList,高速轮询,任务完成就移除
while (futures.size() > 0) {
Iterator<Future<List<ElPushCount>>> iterator = futures.iterator();
//遍历一遍
while (iterator.hasNext()) {
Future<List<ElPushCount>> future = iterator.next();
if (future.isDone()) {
final List<ElPushCount> elPushCounts1 = future.get();
elPushCounts.addAll(elPushCounts1);
iterator.remove();
} else {
Thread.sleep(1);//避免CPU高速运转,这里休息1毫秒,CPU纳秒级别
}
}
}
return ResponseJSONResult.ok("接口查询成功",elPushCounts);
}
}
Service层
在执行异步的的方法上增加@Asyns注解并传入自定义线程池bean名称,实现通过自定义线程池执行异步并发查询,dao层接口省略。
@Service
public class PushElServiceImpl implements PushElService {
@Autowired
private DynamicElMapper dynamicElMapper;
@Override
@Async("taskExecutor")
public Future<List<ElPushCount>> getElPushCountByElType(String elType) {
//根据要素类型查询对应的要素表
final List<ElPushCount> elPushCount = dynamicElMapper.getElPushCount(elType);
System.out.println("统计完毕>>>>>>>>>>>>>>>>>>>>>>***" + elType);
return new AsyncResult<>(elPushCount);
}
}
总结
通过以上方式我们就实现了通过异步多线程方式并发执行多查询并将结果合并返回的业务。
最后
以上就是苹果店员为你收集整理的springboot2.x+自定义线程池实现异步查询并返回结果集需求概述示例代码总结的全部内容,希望文章能够帮你解决springboot2.x+自定义线程池实现异步查询并返回结果集需求概述示例代码总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复