java-基于springboot框架实现线程池异步调用多系统接口
上一篇文章中,介绍了通过ThreadPoolExecutor和Callable实现异步调用多系统接口的思路和方式。这篇基于springboot框架,如何实现异步的调用。
SpringDemoApplication.java
启动类需要添加@EnableAsync注解。
@EnableAsync @SpringBootApplication public class SpringDemoApplication { public static void main(String[] args) { SpringApplication.run(SpringDemoApplication.class, args); }
ThreadPoolConfig.java
配置类里配置线程池参数。
@Configuration public class ThreadPoolConfig { private static final int THREAD = Runtime.getRuntime().availableProcessors() + 1; // 处理器个数+1 public static int corePoolSize = 5; private int maxPoolSize = 10; private int queueCapacity = 1024; private int keepAliveSeconds = 300; private static final String threadNamePrefix = "async-thread-"; @Bean(name = "threadPoolTaskExecutor") public ThreadPoolTaskExecutor threadPoolTaskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); // 设置线程池参数 executor.setMaxPoolSize(maxPoolSize); executor.setCorePoolSize(corePoolSize); executor.setQueueCapacity(queueCapacity); executor.setKeepAliveSeconds(keepAliveSeconds); executor.setThreadNamePrefix(threadNamePrefix); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.initialize(); // 初始化 return executor; } }
AsyncSystemService.java
service层注解配置类。
@Async("threadPoolTaskExecutor") // value值与声明的配置类注册的Bean名一致 @Service public class AsyncSystemService { // @Async("threadPoolTaskExecutor") // 配置在方法上表示方法异步,配置在类上表示类异步 public Future<List<Result>> system1(String params, String url) throws InterruptedException { System.out.println("begin-----" + Thread.currentThread().getName() + "-----" + new Date() + " system1()"); List<Result> res = new ArrayList<>(); /** * 此处为调取各系统接口,并获取返回结果,封装至res内的逻辑 */ Thread.sleep(5000); // 为体现出异步效果,加入延时5s的逻辑;实际业务中删除 System.out.println("end-----" + Thread.currentThread().getName() + "-----" + new Date() + " system1()"); return new AsyncResult<>(res); } // @Async("threadPoolTaskExecutor") public Future<List<Result>> system2(String params, String url) throws InterruptedException { System.out.println("begin-----" + Thread.currentThread().getName() + "-----" + new Date() + " system2()"); List<Result> res = new ArrayList<>(); /** * 此处为调取各系统接口,并获取返回结果,封装至res内的逻辑 */ Thread.sleep(5000); // 为体现出异步效果,加入延时5s的逻辑;实际业务中删除 System.out.println("end-----" + Thread.currentThread().getName() + "-----" + new Date() + " system2()"); return new AsyncResult<>(res); } }
AsyncSystemController.java
controller层。
@RestController @RequestMapping("/async") public class AsyncSystemController { @Autowired private AsyncSystemService asyncSystemService; @GetMapping("/allResult") public List<Result> getAllResult() throws InterruptedException, ExecutionException { LocalDateTime beginTime = LocalDateTime.now(); List<Result> res = new ArrayList<>(); // 汇总结果 Future<List<Result>> future1 = asyncSystemService.system1("params1", "url1"); // 异步访问系统1 Future<List<Result>> future2 = asyncSystemService.system2("params2", "url2"); // 异步访问系统2 List<Future<List<Result>>> futureList = new ArrayList<>(); futureList.add(future1); futureList.add(future2); for (Future<List<Result>> futureItem : futureList) { while (true) { if (futureItem.isDone() && !futureItem.isCancelled()) { // 当前任务结束,且不是被取消的情况,获取任务返回值 res.addAll(futureItem.get()); break; // 获取结果后,一定记得要break,跳出当前线程任务轮询是否结束的循环 } else { Thread.sleep(1); // 当前线程未结束时,每次轮询休息1毫秒,避免CPU高速轮询 } } } Long timeConsuming = Duration.between(beginTime, LocalDateTime.now()).toMillis(); System.out.println("时间消耗:" + timeConsuming); return res; } }
运行打印结果:
可以看出:两个系统分两个线程,同时执行线程任务。总耗时为max(t1, t2)。