2015-05-13 29 views
2

我想找到一個簡單的方法來發送http請求併發到不同的web服務。每個請求是完全相互獨立的。併發http請求到獨立的web服務

目前,我實現這個樣子(只是一個簡化,不注重設計)

讓我們說我有一個清單查詢;

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」後,你在哪裏收集「Future」? –

+0

嗨@akhil_mittal。這是我的問題,我如何從該代碼開始?我如何收集每個線程結果? – justatester

+0

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

回答

1

您似乎創建了一個Callable的列表,並且每個可調用函數將從List<Callable<QueryResult>>返回類型爲QueryResult的結果。提交到ExecutorService後,您將獲得Future。如果你想設置一些最大的時間來等待結果,你可以使用awaitTermination方法以及

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

:那麼以這種方式使用的代碼。 IMO ExecutorCompletionService更適合您的要求,您可以在我的文章dzone中閱讀。

+0

似乎是我正在尋找的答案。我如何將該代碼遷移到番石榴聽音未? – justatester

+0

如果你使用invokeAll這並不意味着在期貨循環期間沒有等待? – justatester

+0

@ bayou.io這就是我從javadoc得到的結果:「執行給定的任務,當返回的列表中的每個元素都爲true時,返回一個持有它們的狀態和結果的期貨列表Future.isDone()。一個完成的任務可能會正常結束或者拋出一個異常。「這並不意味着當我進入期貨循環(收集它們)時,它們都完成了嗎? – justatester

0

您有3個選擇:

在單獨的線程上執行每個請求。由於每個線程都消耗大量內存,因此如果> 100個請求並行運行,您可能會遇到OutOfMemoreError。

將建議的線程數限制爲akhil_mittal。併發請求的數量也將受到限制。

使用異步io庫,例如nio2。它們允許數以千計的同時請求和適度的內存消耗。

+0

是的,我結束了使用第一個選項。我使用了ExecutorService和invokeAll。我找不到一個更好的方法來做到這一點。 – justatester