Java 多线程执行处理,利用CompletableFuturer如何保证顺序?

作者站长头像
站长
· 阅读数 7

我们有1000多条数据,请求1000次第三方个接口, 效率很是低下! 所以我想利用多线程的方式快速的调用完这1000次接口请求并处理响应但是有个问题,线程是在for循环中执行的,调用顺序肯定是错乱的,这就导致接调用后 返回的结果肯定和List中的不匹配了··· 这种情况怎么能保证顺序呢?这是我的代码

public static void main(String[] args) {
        List<String> list=new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            list.add("数据"+i);
        }

        int maximumPoolSize = MAX_POOL_THREAD + 1; //最大线程数 = CPU核数+1(计算密集型)
        ExecutorService executorService = new ThreadPoolExecutor(MAX_POOL_THREAD, maximumPoolSize, 60, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(maximumPoolSize * 2), new ThreadPoolExecutor.CallerRunsPolicy());
        CompletableFuture[] futures = new CompletableFuture[list.size()];
        for (int i = 0; i < list.size(); i++) {
            String s = list.get(i);
            logger.info("线程执行前"+s);
            int finalI = i;
            futures[i]= CompletableFuture.runAsync(() -> {
                logger.info("开始执行异步线程->>"+s);
                //调用接口
                //根据接口返回值判断list中的值 是否匹配    问题是返回肯定和List的值不不配····

                }, executorService); // 用自定义线程池
        }

        // 所有请求完成后处理逻辑
        CompletableFuture.allOf(futures).thenRun(() -> {
            logger.info("线程执行完毕:{}",JSON.toJSONString(futures));
            //调用发送短信
        }).thenRun(() -> executorService.shutdown()); // 所有任务完成后关闭线程池
    }

Java 多线程执行处理,利用CompletableFuturer如何保证顺序?

回复
1个回答
avatar
test
2024-06-28
public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    for (int i = 0; i < 20; i++) {
        list.add("数据" + i);
    }

    int maximumPoolSize = MAX_POOL_THREAD + 1; //最大线程数 = CPU核数+1(计算密集型)
    ExecutorService executorService = new ThreadPoolExecutor(MAX_POOL_THREAD, maximumPoolSize, 60, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(maximumPoolSize * 2), new ThreadPoolExecutor.CallerRunsPolicy());

    List<CompletableFuture<String>> futures = new ArrayList<>();
    for (int i = 0; i < list.size(); i++) {
        String s = list.get(i);
        logger.info("线程执行前" + s);
        futures.add(CompletableFuture.supplyAsync(() -> {
            logger.info("开始执行异步线程->>" + s);
            //调用接口
            //根据接口返回值判断list中的值 是否匹配
            //返回处理后的结果
            return s + "处理后的结果"; 
        }, executorService)); // 用自定义线程池
    }

    // 所有请求完成后处理逻辑
    CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).thenRun(() -> {
        List<String> results = futures.stream().map(CompletableFuture::join).collect(Collectors.toList());
        logger.info("线程执行完毕:{}", JSON.toJSONString(results));
        //调用发送短信
    }).thenRun(() -> executorService.shutdown()); 
}
回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容