简体   繁体   English

报告ThreadPool中的异常并关闭

[英]Reporting exceptions in a ThreadPool and shutdown

So I have this Java piece of code where I need to do some work on a bunch of items. 所以我有一段Java代码,我需要在一堆项目上做一些工作。 I decided to parallelize this to get some extra boost and I though to use a ThreadPoolExecutor. 我决定将其并行化以获得额外的提升,但我使用ThreadPoolExecutor。 The problem is that the work I need to do can throw an exception... 问题是我需要做的工作可以抛出异常......

Now I would like to shutdown the entire job to stop as soon as an error is encountered and report it back so I can handle it. 现在我想在遇到错误时立即关闭整个作业并将其报告回来以便我可以处理它。 Looking online, I found that the normal way this should be done is via ExecutorCompletionService and analyzing the Future results. 在线查看,我发现应该这样做的正常方法是通过ExecutorCompletionService并分析Future结果。 However, this won't let me shut everything down when the first error comes by, as there is no way to loop over based on which task finishes first... 但是,当第一个错误发生时,这不会让我关闭所有内容,因为没有办法根据哪个任务首先完成循环...

So I did something that I thought was rather hacky and I'm curious if there is a better way to handle this. 所以我做了一些我认为相当hacky的东西,我很好奇是否有更好的方法来解决这个问题。 What I did was: 我做的是:

1) Have each Runnable that I will execute have a field for the Throwable that it might execute. 1)让我将执行的每个Runnable都有一个可执行的Throwable字段。 2) Override the TPE's "afterExecute" method and check if any checked exception got thrown (which gets recorded in the Runnable) or any unchecked one gets thrown (which should be reported in the second parameter of this method). 2)覆盖TPE的“afterExecute”方法并检查是否抛出了任何已检查的异常(它被记录在Runnable中)或者任何未经检查的异常被抛出(应该在此方法的第二个参数中报告)。 If any did, then I issue a shutdownNow() on the TPE. 如果有,那么我在TPE上发出shutdownNow()。

Again, this seems a bit hacky and I am wondering if there is something I am missing. 再次,这似乎有点hacky,我想知道是否有我遗失的东西。 Thanks in advance! 提前致谢!

Look at ExecutorService.invokeAny : 看看ExecutorService.invokeAny

Executes the given tasks, returning the result of one that has completed successfully (ie, without throwing an exception), if any do. 执行给定的任务,返回已成功完成的任务的结果(即,不抛出异常),如果有的话。 Upon normal or exceptional return, tasks that have not completed are cancelled. 在正常或特殊退货时,未完成的任务将被取消。 The results of this method are undefined if the given collection is modified while this operation is in progress. 如果在此操作正在进行时修改了给定集合,则此方法的结果是不确定的。

It looks it does the exact same thing you are trying to do... if I understood your problem correctly. 它看起来与你试图完全相同的事情......如果我正确理解你的问题。

However for cancel to do anything, you have to make your Callable tasks interrupt aware. 但是,对于取消执行任何操作,您必须使您的Callable任务中断。 But that applies no matter how you try to cancel your tasks. 但无论您如何尝试取消任务,这都适用。

EDIT : 编辑
This is not what you need; 这不是你需要的; I misread the javadoc. 我误读了javadoc。 Here's another solution: you could put all your Future 's in a list and then have a semi-busy while loop where you check periodically on each futureList.get(i).get(100, TimeUnits.MILLISECONDS) and you can catch an exception and act accordingly. 这是另一个解决方案:你可以把你所有的Future放在一个列表中然后有一个半繁忙的while循环,你定期检查每个futureList.get(i).get(100, TimeUnits.MILLISECONDS)你可以捕获一个例外并采取相应行动。 However, this no more "elegant" than your solution. 但是,这不比你的解决方案更“优雅”。 It seems that afterExecute was made to do what you want anyway. 似乎afterExecute无论如何都要做你想做的事。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM