【问题标题】:Number of tasks completed while executor is still running执行器仍在运行时完成的任务数
【发布时间】:2013-04-24 19:45:15
【问题描述】:

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

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

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

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

谢谢

【问题讨论】:

  • 谢谢。我有两种类型的任务 A 和 B。我想知道所有类型 A 和类型 B 的任务什么时候完成。类型 A 和 B 在结构上是相同的,但类型 A 使用的数据更大,这就是为什么它需要更长的时间。我认为在任务类中定义以下变量会很好:1)final static int NTYPEATOComplete; 2) static int nTypeATasksCompleted;3) static long timeOfComepletion_A;和类型 B 相同。然后,​​在 call() 结束时,我添加 nTypeATasks++ 并检查是否 =100。如果是这样,我会记录完成时间。可以吗?还有 #workers=nCPU-1 因为任务很重。

标签: java multithreading executorservice executor


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    我会建立一个List&lt;Future&gt;,您可以定期轮询它以查看完成了多少。

    【讨论】:

      猜你喜欢
      • 2016-03-05
      • 1970-01-01
      • 1970-01-01
      • 2022-08-19
      • 1970-01-01
      • 2021-12-26
      • 1970-01-01
      • 2022-07-13
      • 2023-02-24
      相关资源
      最近更新 更多