如何正确捕获 Executor 中的 RuntimeException?
假设我有以下代码:
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(myRunnable);
现在,如果 myRunnable
抛出 RuntimeExcpetion
,我怎样才能捕获它?一种方法是为 newSingleThreadExecutor()
提供我自己的 ThreadFactory
实现,并为 Thread
设置自定义 uncaughtExceptionHandler
是从中出来的。另一种方法是将 myRunnable 包装到包含 try-catch 块的本地(匿名)Runnable。也许还有其他类似的解决方法。但是……不知怎的,这感觉很脏,我觉得不应该这么复杂。有干净的解决方案吗?
Say that I have the following code:
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(myRunnable);
Now, if myRunnable
throws a RuntimeExcpetion
, how can I catch it? One way would be to supply my own ThreadFactory
implementation to newSingleThreadExecutor()
and set custom uncaughtExceptionHandler
s for the Thread
s that come out of it. Another way would be to wrap myRunnable
to a local (anonymous) Runnable
that contains a try-catch -block. Maybe there are other similar workarounds too. But... somehow this feels dirty, I feel that it shouldn't be this complicated. Is there a clean solution?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
干净的解决方法是使用
ExecutorService.submit()
而不是execute()
。这将返回一个Future
,您可以使用它来检索任务的结果或异常:The clean workaround is to use
ExecutorService.submit()
instead ofexecute()
. This returns you aFuture
which you can use to retrieve the result or exception of the task:在另一个可捕获运行时异常并处理它们的可运行对象中装饰可运行对象:
Decorate the runnable in another runnable which catches the runtime exceptions and handles them:
为什么不调用
ExecutorService#submit()
,获取Future
返回,然后在调用Future#get()
?Why not call
ExecutorService#submit()
, get theFuture
back and then handle possible exceptions yourself when callingFuture#get()
?skaffman 是正确的,因为使用
submit
是最干净的方法。另一种方法是子类ThreadPoolExecutor< /code>
并覆盖
afterExecute(Runnable, Throwable)
。如果您遵循此方法,请务必调用execute(Runnable)
而不是submit(Runnable)
或afterExecute
不被调用。根据 API 描述:
skaffman is correct in that using
submit
is the cleanest approach. An alternative approach is to subclassThreadPoolExecutor
and overrideafterExecute(Runnable, Throwable)
. If you follow this approach be sure to callexecute(Runnable)
rather thansubmit(Runnable)
orafterExecute
will not be invoked.Per the API description:
提交到 ThreadPoolExecutors 的任务(
Callable
或Runnable
)将被转换为FuturnTask
,包含一个名为 < b>callable
等于您提交的任务。 FuturnTask 有自己的 run 方法,如下所示。c.call()
中抛出的所有异常或可抛出异常都将被捕获并放入名为outcome
的 prop 中。 将会抛出outcome
FuturnTask.run From Jdk1.8 Source Code :
当调用FuturnTask的
get
方法时,如果你想捕获异常,1. skaffman's answer
2. overwrite `afterExecute` when you new a ThreadPoolExecutor
a task(
Callable
orRunnable
) submitted toThreadPoolExecutors
will be convert to aFuturnTask
, contains a prop namedcallable
equals the task you submit. FuturnTask has its ownrun
method as follows. All exception or throwable throwed inc.call()
will be catched and put into a prop namedoutcome
. When calling FuturnTask'sget
method,outcome
will be throwedFuturnTask.run From Jdk1.8 Source Code
if you want catch the exception :
1. skaffman's answer
2. overwrite `afterExecute` when you new a ThreadPoolExecutor