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)。

 

posted @   DoubleFishes  阅读(52)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
  1. 1 今时意所属 你要不要买菜
  2. 2 夏夜最后的烟火 颜人中
  3. 3 夜泊秦淮 Ice Paper
  4. 4 脸红接收处 Plggy
  5. 5 那些花儿 朴树
夏夜最后的烟火 - 颜人中
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

Not available

点击右上角即可分享
微信分享提示