所以我有这段Java代码,我需要在一堆项目上做一些工作。我决定将其并行化以获得一些额外的提升,并且我打算使用ThreadPoolExecutor。问题是我需要做的工作可能会抛出异常…
现在我想关闭整个作业,以便在遇到错误时立即停止并报告它,以便我可以处理它。在网上看,我发现正常的方式应该是通过ExecutorCompletionService和分析未来的结果。然而,这不会让我在第一个错误出现时关闭一切,因为没有办法根据哪个任务先完成来循环…
所以我做了一些我认为相当hackky的事情,我很好奇是否有更好的方法来处理这个问题。我所做的是:
1)让我将要执行的每个Runnable都有一个它可能执行的Throwable的字段。2)覆盖TPE的"afterExecute"方法,并检查是否有任何已检查的异常被抛出(记录在Runnable中)或任何未检查的异常被抛出(应在该方法的第二个参数中报告)。如果有,那么我在TPE上发出一个shutdownNow()。
再次,这似乎有点黑客,我想知道是否有什么我错过了。提前感谢!
查看ExecutorService.invokeAny:
执行给定的任务,如果有任务成功完成,则返回成功完成的任务的结果(即没有抛出异常)。在正常或异常返回时,未完成的任务将被取消。如果在执行此操作时修改了给定的集合,则此方法的结果是未定义的。
它看起来和你想做的完全一样…如果我理解对了你的问题
然而,为了取消做任何事情,您必须使您的Callable
任务中断感知。但无论你如何尝试取消任务,这都适用。
编辑:
这不是你需要的;我读错了javadoc。这里有另一个解决方案:你可以把所有的Future
放在一个列表中,然后有一个半繁忙的while循环,你可以定期检查每个futureList.get(i).get(100, TimeUnits.MILLISECONDS)
,你可以捕捉一个异常,并采取相应的行动。然而,这并不比您的解决方案更"优雅"。似乎afterExecute
无论如何都是做你想做的。