ExecutorCompletionService
(送信されたタスクを記憶するコールバックを備えたスレッドプール)は間抜けなgitのようです:
CompletionService<Response> executorService =
new ExecutorCompletionService<>(Executors.newFixedThreadPool(10));
int totalExternal = 0;
for(Item item : items){
if(item is external){
executorService.submit(externalCall(item));
++totalExternal;
}
if(item is internal){
populate response object and add to list
}
}
for (int i = 0; i < totalExternal; ++totalExternal) {
addAsynchResultToResponseList(executorService.take().get());
}
わかりexternalCall(item)
やすくするために、次のように定義されています。
Callable<Response> externalCall(Item item) {
return new Callable<Response>() {
//...
}
}
明らかに、非同期にすると、結果リストは任意の順序になる可能性があります。
別のアプローチは、通常を使用しExecutorService
、中間を使用することList<Future<Response>>
です。秘訣は、AsyncResult
ラッパーを使用して内部応答をラップすることFuture
です(ラッパーを使用して、すぐに実行され、渡された値を返します)。
List<Future<Response>> futures = new ArrayList<>();
for(Item item : items){
if(item is external){
futures.add(executorService.submit(externalCall(item)));
}
if(item is internal){
futures.add(new AsyncResult(synchResponse));
}
}
これで、を簡単に繰り返すことができますfutures
。AsyncResult
値は作成時にすでにコンピューターであったため、すぐに戻ります(synchResponse
)。Future
ただし、スレッドプールからsが返されるのを待つ必要があります。
Future.get()
これにより、元の例外を取得できることを忘れないでください。また、Future
リスト内のsの順序は元のアイテムの順序と同じであるため、n番目Future
が失敗した場合は、items
リスト内のn番目のアイテムが原因でした。