2013-04-24 94 views
0

有没有什么方法可以找到调用invokeAll()后完成的任务数?看起来,当所有线程完成时,它返回完成任务的布尔值列表。执行程序仍在运行时完成的任务数

我有一个由1000个任务组成的池,并且希望以100个时间间隔看看他们,而不必将它们分成100个任务批次。

我也出于兼容性原因必须与Java 6一起工作,所以更新的方法将无济于事。

此外,作为一个侧面的问题:invokeAll()是否以FIFO方式处理任务?也就是说,这些任务是否以他们添加到任务列表的顺序开始?

感谢

+0

谢谢。我有两种类型的任务A和B.我想知道何时完成了所有类型A和类型B任务。类型A和B在结构上是相同的,但类型A处理的数据更大,这就是为什么它需要更长的时间。我认为在任务类中定义以下变量会很好:1)final static int NTYPEATOComplete; 2)static int nTypeATasksCompleted; 3)static long timeOfCplepletion_A;对于类型B也是如此。然后,在call()的结尾添加nTypeATasks ++并检查是否= 100。如果是这样,我记录完成时间。可以吗?由于任务繁重,还有#workers = nCPU-1。 – user1288502 2013-04-25 11:42:10

回答

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方式的任务?也就是说,这些任务是否以他们添加到任务列表的顺序开始?

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

0

任务将按照您指定的顺序添加,并且如果您有多个线程,则按照该顺序大致开始。如果他们花费相同的时间,他们完成的订单将大致按此顺序排列。

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

相关问题