2015-05-13 2 views
2

Я пытаюсь найти простой способ отправки HTTP-запроса одновременно с различными веб-службами. каждый запрос полностью независим друг от друга.одновременный запрос http к независимым веб-службам

в настоящее время, моя реализация выглядит следующим образом (только упрощение, не обращает внимание на дизайн)

скажет, у меня есть список запросы;

public class Service { 

     private List<HttpClient> httpClients; // one for each web service 

     public List<QueryResult> doQueries(List<Query> queries) { 

       ExecutorService service = Executors.... ; 
       List<Callable<QueryResult>> .... ; 

       for (Query q : queries) { 
          Future<> ..... 
       } 

       service.invokeAll(...) ; 

       ***// what should i do from here ? 
       // how should i wait all those tasks to finish ?*** 


     } 
} 

мой вопрос в частности, что. как подождать?

+0

Пожалуйста, поделитесь полным кодом. Где вы собираете «Будущее» после отправки запросов в «ExecutorService»? –

+0

привет @akhil_mittal. это мой вопрос, как я могу исходить из этого кода? как мне собрать каждый результат нити? – justatester

+0

['Fork and Join'] (https://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html)? –

ответ

1

Вы, кажется, создаете список Callable, и каждый вызываемый будет возвращать результат типа QueryResult как видно из List<Callable<QueryResult>>. Вы получите Future после отправки их на номер ExecutorService. Поэтому используйте код таким образом:

List<Future<QueryResult >> futures = executorService.invokeAll(callables); 
for(Future<QueryResult> future : futures){ 
    System.out.println("future.get = " + future.get()); 
} 
executorService.shutdown(); 

Если вы хотите установить какое-то максимальное время ожидания результата вы можете использовать awaitTermination метод, а также. IMO ExecutorCompletionService больше подходит для ваших требований, и вы можете прочитать об этом в моей статье по адресу dzone.

+0

, кажется, ответ, который я искал. как я могу перенести этот код на guava listenfuture? – justatester

+0

Если вы используете invokeAll, это не значит, что вы не ожидаете во время цикла на фьючерсах? – justatester

+0

@ bayou.io это то, что я получил от javadoc: «Выполняет заданные задачи, возвращая список фьючерсов, сохраняющих их статус и результаты, когда все завершено. Future.isDone() истинно для каждого элемента возвращаемого списка. завершенная задача могла бы завершиться либо нормально, либо путем исключения исключения ». Не означает ли это, что, когда я иду на цикл фьючерсов (их сбор), они все завершены? – justatester

0

У вас есть 3 варианта:

выполнить каждый запрос на отдельном потоке. Поскольку каждый поток потребляет много памяти, вы можете получить OutOfMemoreError, если> 100 запросов выполняются параллельно.

Ограничить количество потоков, предложенных akhil_mittal. Количество одновременных запросов также будет ограничено.

Используйте библиотеку async io, например. nio2. Они позволяют тысячи одновременных запросов с умеренным потреблением памяти.

+0

Да, я закончил использовать первый вариант. Я использовал ExecutorService и invokeAll. я не мог найти лучшего способа сделать это. – justatester

Смежные вопросы