我有3个 FutureTask<T> 对象。我希望它们被异步处理。但是,一旦FutureTasks的get()方法之一不返回null时,我就想继续,即我的方法(包装器)返回并且不等待其他两个FutureTasks被处理。
我想到了类似的东西:

private File wrapper(final File file) {
    ExecutorService executors = Executors.newCachedThreadPool();
    File returnFile;
    FutureTask<File> normal= ...
    FutureTask<File> medium=...
    FutureTask<File> huge=...

    executors.execute(normal);
    executors.execute(medium);
    executors.execute(huge);
    try {
        if((returnFile=normal.get()) != null ||
           (returnFile=medium.get()) != null ||
           (returnFile=huge.get()) != null)

            return returnFile;

    } catch(ExecutionException | InterruptedException e) { }
}

我不确定如何以适当的方式捕获异常(由get()抛出),因为我假设它们将被抛出,因为我只是返回而无需等待其他两个任务完成。此外,我怀疑代码是否会按预期工作。我觉得我已经接近解决方案,但是缺少一些东西。

最佳答案

我可以建议检查FutureTask::isDone吗?

然后将是这样的:

while(true) {
    if (normal.isDone()) {
        return normal.get();
    }
    if (medium.isDone()) {
        return medium.get();
    }
    if (huge.isDone()) {
        return huge.get();
    }
}

编辑:
只要有一个结果,您就可以将其他任务添加到其他任务中。

使用cancel不是您要查找的内容,因为它很可能总是返回normal.get()的结果,因为文档已经指出:

等待必要的计算完成,然后检索
其结果。

为了澄清以上内容:
如果使用FutureTask::get,则调用的第一个FutureTask很可能会阻塞并等待结果可返回。

编辑2:

将循环包装到一个由ExecutorService执行的新Runnable中,将第一个可用的结果传递给另一个方法或实现一个Callback,不再需要等待。

07-24 19:00
查看更多