Java 当一个未来任务具有预期结果时继续

Java 当一个未来任务具有预期结果时继续,java,asynchronous,executorservice,futuretask,Java,Asynchronous,Executorservice,Futuretask,我有三个物体。我希望它们是异步处理的。但是,只要一个FutureTasks的get()方法没有返回null我就想继续,也就是说,我的方法(包装器)返回并且不等待其他两个FutureTasks被处理。 我想到了这样的事情: private File wrapper(final File file) { ExecutorService executors = Executors.newCachedThreadPool(); File returnFile; FutureTas

我有三个物体。我希望它们是异步处理的。但是,只要一个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) { }
}
私有文件包装器(最终文件){
ExecutorService executors=executors.newCachedThreadPool();
文件返回文件;
未来任务正常=。。。
未来任务介质=。。。
未来任务巨大=。。。
执行人。执行(正常);
执行人。执行(中等);
执行人。执行(巨大);
试一试{
如果((returnFile=normal.get())!=null | |
(returnFile=medium.get())!=null | |
(returnFile=maging.get())!=null)
返回文件;
}catch(ExecutionException | interruptedeexception e){
}

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

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

那么应该是这样的:

while(true) {
    if (normal.isDone()) {
        return normal.get();
    }
    if (medium.isDone()) {
        return medium.get();
    }
    if (huge.isDone()) {
        return huge.get();
    }
}
编辑: 只要手头有一个结果,您就可以完成其他任务

使用并不是您想要的,因为它很可能总是返回normal.get()的结果,因为文档已经说明:

如有必要,等待计算完成,然后检索 它的结果

为了澄清上述情况: 如果使用FutureTask::get,则调用get on的第一个FutureTask很可能会阻塞并等待结果返回

编辑2:


将该循环包装到一个新的Runnable中,由ExecutorService执行,将第一个可用的结果传递给另一个方法或实现回调,这样就没有更多的忙等待了。

我想到了使用BlockingQueue来设计它。您可以使用done方法将结果提交到BlockinQueue中来扩展任务,一旦客户端收到第一个结果,它就会取消其他任务。另一方面,相反。它似乎将结果序列化为imself和。

这里的问题是,您可以将结果立即用于大型任务,但不必要地阻止您等待长时间运行的任务正常运行。如果我正确理解了您的需求,那么只完成其中一个就足够了。我看到
FutureTask
会公开done(),以便您在一个准备就绪时进行覆盖。您可以取消其他任务(整个竞争任务列表)。基本上,您再创建一个任务来等待来自done()的信号;未来{p.tryComplete(img2)};未来{p.tryComplete(img1)};p、 future此处p.future将等待图像1或2,以先完成者为准。另一个将在tryComplete失败,错误不会传播到任何地方,因为它是为此目的设计的,只完成第一个结果。在Java8中可能有类似的东西。忙吗,等等?多好的并行处理杰作啊!我的本意不是促进忙碌的等待。我只是试图说明FutureTask::get.:)的问题不过,谢谢你指出这一点!请添加一个链接以取消方法文档,说明在ExecutorService中执行busy wait如何降低busy wait?No busy wait与回调的关系。要么自己使用,要么自己实现。也许是因为我不是以英语为母语的人,但我认为我的句子从德语的角度讲是有意义的。