Завершенное будущее, чтобы поразить многократную службу отдыха и объединить результат - PullRequest
1 голос
/ 20 июня 2020

У меня вопрос:

У меня есть точка отдыха, которая дает мне результат 1000 на страницу каждый раз, когда мне нужно увеличить страницу и сделать новый вызов отдыха с увеличенным номером страницы; pagenum будет 0,1,2, до всей страницы. Я сделал вызов asyn c, используя завершаемое будущее, передав pagenum.

Итак, предположим, что общая страница равна 5, поэтому 5 потоков будут go и получат результат, тогда я должен получить результат и объединить все результат.

для этого я использую --respon = resp.get (); но я прочитал его блокирующий вызов ..

, поэтому мой вопрос в том, как получить результаты асинхронно и объединить их. в приведенном ниже коде я делаю future .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();
                                }
                                
            }
           
         }

1 Ответ

1 голос
/ 20 июня 2020

Одним из вариантов может быть создание комбинированного будущего:

    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();
    }

Пример выше должен помочь вам запустить запрос всех страниц параллельно и обработать результаты после обработки всех фьючерсов.

Если вы хотите обрабатывать все результаты одновременно, независимо от остальных, чтобы обработка ответа была асинхронной c, вы можете использовать метод 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();
    }

Я бы также рекомендовал использовать ограничение тайм-аута on CombinedFutre.get ()

combinedFuture.get(50, TimeUnit.SECONDS);

Эта статья должна помочь вам с более подробной информацией https://www.baeldung.com/java-completablefuture

...