1000 個のタスクのプールがあり、それらを 100 個のタスクのバッチに分割することなく、100 個の間隔でそれらを調べたいと考えています。
を使用してすべてのジョブが完了するExecutorCompletionService
のを待つのではなく、1 つのジョブが完了したら通知を受け取ることができる を使用することを検討する必要があります。次に、完成した各ジョブをコレクションに入れ、100 個になったらアクションを実行します。invokeAll()
たぶん次のようなもの:
CompletionService<Result> ecs = new ExecutorCompletionService<Result>(executor);
for (Callable<Result> s : solvers)
ecs.submit(s);
int n = solvers.size();
List<Result> batch = new ArrayList<Result>();
for (int i = 0; i < n; ++i) {
Result r = ecs.take().get();
batch.add(r);
if (batch.size() >= 100) {
process(batch);
batch.clear();
}
}
if (!batch.isEmpty()) {
process(batch);
}
invokeAll() は FIFO 方式でタスクを処理しますか? つまり、タスクはタスク リストに追加された順序で開始されますか?
タスクは、FIFO 方式でスレッド プールに送信され、FIFO 順序でスレッドによってデキューされます。ただし、各スレッドがジョブを取得すると、競合状態が発生し、実際のタスクの「開始」と確実に終了する順序が変更される可能性があります。