0

有什么方法可以在调用 invokeAll() 后找到完成的任务数?似乎当所有线程都完成时,它会返回已完成任务的布尔值列表。

我有一个包含 1000 个任务的池,并且想以 100 个间隔查看它们,而不必将它们分成 100 个任务批次。

出于兼容性原因,我还必须使用 Java 6,因此更新的方法无济于事。

另外,作为一个附带问题:invokeAll() 是否以 FIFO 方式处理任务?也就是说,任务是否按照它们添加到任务列表的顺序开始?

谢谢

4

2 回答 2

3

我有一个包含 1000 个任务的池,并且想以 100 个间隔查看它们,而不必将它们分成 100 个任务批次。

您应该考虑使用 ,ExecutorCompletionService它允许您在单个作业完成后收到通知,而不必等待所有作业完成使用invokeAll(). 然后,您可以将每个已完成的作业放入一个集合中,然后在获得 100 个时对它们进行操作。

也许是这样的:

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 方式处理任务?也就是说,任务是否按照它们添加到任务列表的顺序开始?

任务以先进先出的方式提交到线程池,并由线程也以先进先出的顺序出列。但是,一旦每个线程都有工作,就会出现竞争条件,这可能会导致实际任务“开始”并肯定完成的一些重新排序。

于 2013-04-24T19:47:18.183 回答
0

任务将按照您指定的顺序添加,如果您有多个线程,则大致按该顺序启动。如果他们花费相同的时间,他们完成的顺序将大致按照该顺序。

我会建立一个List<Future>你可以定期轮询的,看看有多少已经完成。

于 2013-04-24T19:48:18.220 回答