我有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,不再需要等待。