首页 > 解决方案 > 完成未来打多个休息服务并结合结果

问题描述

我有个问题:

我有休息点,每次我必须增加页面并使用增加的页码进行新的休息调用时,每页给我 1000 个结果;pagenum 值将是 0,1,2,直到总页数。我通过传递 pagenum 使用可完成的未来进行了异步调用。

所以假设总页数是 5,所以 5 个线程会去得到结果,然后我必须得到结果并结合所有结果。

为此,我正在使用 --respon = resp.get(); 但我读了它的阻塞电话..

所以我的问题是如何异步获取结果并将其组合起来。在下面的代码中,我正在做未来的 .get() 它将停止异步运行代码。

请给出意见 !!!!!!!!

for (int pagenum = 1; pagenum <=totalPage; pagenum++) {
            
        String respon=   CompletableFuture.supplyAsync(() -> {
                return new RestTemplate().exchange(getUsersByID(roleId, maxCount, 
                        pagenum), HttpMethod.GET,
                        entity, String.class).getBody();
            });             
                                try {
                                    respon = resp.get();
                                    
                                } catch (InterruptedException | ExecutionException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                }
                                
            }
           
         }

标签: javamultithreadingrest

解决方案


一种选择可能是创造结合的未来:

    int MAX_PAGE_NUM = 100;
    List<CompletableFuture<String>> futures = new ArrayList<>();
    for(int pagenum = 1; pagenum < MAX_PAGE_NUM; pagenum++) {
        futures.add(  CompletableFuture.supplyAsync(() -> {
            return new RestTemplate().exchange(getUsersByID(roleId, maxCount,
                pagenum), HttpMethod.GET,
                entity, String.class).getBody();
        }), executor);
    }

    CompletableFuture combinedFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[MAX_PAGE_NUM]));
    try {
        combinedFuture.get();
        
        for (CompletableFuture<String> future : futures) {
            String response = future.get();
            //process the response
        }
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }

上面的示例应该可以帮助您并行运行所有页面请求,并在处理完所有期货后处理结果。

如果您想同时处理每个结果,而不考虑其余结果,以便响应处理是异步的,您可以使用 thenApply() 方法。

    int MAX_PAGE_NUM = 100;
    List<CompletableFuture<String>> futures = new ArrayList<>();
    for(int pagenum = 1; pagenum < MAX_PAGE_NUM; pagenum++) {
        futures.add(  CompletableFuture.supplyAsync(() -> {
            return new RestTemplate().exchange(getUsersByID(roleId, maxCount,
                pagenum), HttpMethod.GET,
                entity, String.class).getBody();
        }).thenApply( (s) -> {
            //process the response concurrently
            return s;
        }), executor);
    }

    CompletableFuture combinedFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[MAX_PAGE_NUM]));

    try {
        combinedFuture.get();
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }

我还建议对 combineFututre.get() 使用超时限制

combinedFuture.get(50, TimeUnit.SECONDS);

本文应该可以帮助您了解更多详细信息https://www.baeldung.com/java-completablefuture


推荐阅读