2016-09-20 43 views

回答

3

更好的方法是使用invokeAll()方法而不是submit()。您需要提供一個Callable的集合,它將以與您的任務相同的順序返回一個Futures集合。而且,invokeAll()可以讓你定義超時,所以你不需要鎖存器。它會是這樣的:

List<Callable> jobs = new ArrayList<>(requests.size()); 
for (String request : requests) { 
    jobs.add(new MyCallable(request)); 
} 
List<Future<ProcessedResponse>> futures = executor.invokeAll(jobs, timeout, TimeUnit.MILLISECONDS); 
Iterator<String> it = requests.iterator(); 
for (Future<ProcessedResponse> future: futures) { 
    String request = it.next(); // This request corresponds to this future 
    if (future.isDone()) { 
     results.add(new Result(request, future.get())); 
    } else { 
     future.cancel(true); 
    } 
} 
+0

聽起來不錯,但我唯一的擔心是關於集合的命令,我需要一個特定的集合類或任何會做? 「維護秩序」的說法在哪裏陳述? – gvasquez

+0

所有'List's保存元素順序。所以,你需要傳遞一個清單給執行者,它會返回你一份期貨清單。以下是有關'invokeAll()'方法的文檔,請查看「Returns」部分:https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html# invokeAll-java.util.Collection-long-java.util.concurrent.TimeUnit- –

+0

只是一個小的錯字:本地循環變量應該是單數而非複數,即「未來」,因爲「期貨」已經是整個列表。 oops:它也會讀取「fugure.get()」,而不是「future.get()」 – gvasquez