2
我試圖使用ThreadPoolExecutor以及Future(結果)和Callable(要執行的任務),但我找不到一個簡單的方法來關聯輸入(Callable)與相應的結果(未來),似乎唯一明智的方法是創建一個包含所有項目的包裝器(example),但這對於這樣一個簡單的任務可能會造成太多開銷。ThreadPoolExecutor,Futures:關聯請求和響應
我錯了嗎?任何建議的選擇?
我試圖使用ThreadPoolExecutor以及Future(結果)和Callable(要執行的任務),但我找不到一個簡單的方法來關聯輸入(Callable)與相應的結果(未來),似乎唯一明智的方法是創建一個包含所有項目的包裝器(example),但這對於這樣一個簡單的任務可能會造成太多開銷。ThreadPoolExecutor,Futures:關聯請求和響應
我錯了嗎?任何建議的選擇?
更好的方法是使用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);
}
}
聽起來不錯,但我唯一的擔心是關於集合的命令,我需要一個特定的集合類或任何會做? 「維護秩序」的說法在哪裏陳述? – gvasquez
所有'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- –
只是一個小的錯字:本地循環變量應該是單數而非複數,即「未來」,因爲「期貨」已經是整個列表。 oops:它也會讀取「fugure.get()」,而不是「future.get()」 – gvasquez