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?
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
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:
Why not call
ExecutorService#submit()
, get theFuture
back and then handle possible exceptions yourself when callingFuture#get()
?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: