Java-使用invokeAll按顺序获取未来结果,但仅限于某些线程

时间:2012-10-28 19:45:16

标签: java threadpool future executors

我...真的不知道如何更好地说出标题。但基本上,我所拥有的是一个线程池,所有这些线程忙着工作。我希望他们按照分配的顺序报告他们的结果,但同时,我想分批工作。为了说明,例子是

ExecutorService exec = Executors.newFixedThreadPool(8);

class MyCallable implements Callable<byte[]> {
    private final int threadnumber;

    MyCallable(int threadnumber){
        this.threadnumber = threadnumber;
    }

    public byte[] call() {
        //does something
    }
}
List<Callable<byte[]>> callables = new ArrayList<Callable<byte[]>>();

for(int i=1; i<=20; i++) {
    callables.add(new MyCallable(i));
}
try {
    List<Future<byte[]>> results = exec.invokeAll(callables);
    for(Future<byte[]> result: results) {
            System.out.write(result.get(), 0, result.get().length);
    }

基本上,池线程有8个线程,最后我有20个任务(这些只是示例)。如果我理解正确的话,它现在的工作方式是它等待所有20个任务完成后再按顺序输出它们(从1到20)。该程序应该做的是输出连续的字节流(由线程处理,因为我需要保持顺序完整,我使用了未来的接口)。虽然我不介意等到所有20个任务都完成,但无论如何都要让线程按顺序输出。

如果没有办法,或者我只是完全误解了invokeAll的工作方式,那么澄清也是值得欢迎的。提前谢谢!执行官有点困惑,因为我刚刚了解了它们。

随机附录,我甚至被允许从可调用的函数返回一个字节数组?

2 个答案:

答案 0 :(得分:5)

invokeAll()等待所有结果在返回之前计算。

逐个使用循环和submit(),此方法立即返回带有挂起结果的Future:

...
for(int i=1; i<=20; i++) {
    results.add(exec.submit(new MyCallable(i))); 
}
try {
    for(Future<Integer> result: results) {
            System.out.write(result.get(), 0, result.get().length);
    }
}
...

答案 1 :(得分:0)

使用invokeAll也可以实现。

 List<Future<byte[]>> results = exec.invokeAll(callables); 

它将返回未来的对象列表。

ThreadPoll将以随机顺序执行任务。任务执行顺序无法控制。

未来对象

  1. 它是在ThreadPool中提交的任务的参考。

  2. 它有一个方法 get()。它是一种阻塞调用方法。如果调用get()方法,则调用将等待任务完成。

  3. 如何确保任务提交顺序

    结果顺序在callables顺序中相同。甚至线程池也会以不同的顺序执行,我们可以按相同的顺序检索。

    对于前。

    三个任务1,2,3

    1&amp; 3 - &gt;完成。

    2 ------&gt;需要很长时间才能执行。

    调用invokeAll方法后,它将以相同的顺序返回List of Future。

    任务1:未来#get方法返回结果,因为它已经完成

    任务2:未来#get方法等待任务完成。

    即使第三个任务完成,迭代也会等到第二个任务完成。它不会从第三个线程得到结果。