[concurrency-interest] ScheduledThreadPoolExecutor lost exception?

Doug Lea dl at cs.oswego.edu
Tue May 24 19:46:50 EDT 2005


TAlison at ameritrade.com wrote:
> I'm extending ScheduledThreadPoolExecutor to implement the afterExecute
> method so that I can log any runtime exceptions thrown by scheduled
> tasks. However, I've found that runtime exceptions do not actually make
> it to afterExecute. It appears the Sync used by the FutureTask that
> wraps the scheduled task catches the exception and calls setException
> but does not rethrow it. Thus, the runTask method of
> ThreadPoolExecutor$Worker never passes it to to afterExecute. 
>  
> So, even if an exception is thrown, it is masked by the FutureTask
> wrapper and the Worker class thinks the task ran successfully. Is this a
> bug or am I interpreting the usage of afterExecute incorrectly? I'm
> running JDK 5.0 Update 3.
>  


Ignore my previous responses. Sorry.

The current behavior is correct. It is however confusing
(even to me!) and should/will be clarified.

Submitted actions in ScheduledThreadPoolExecutors are
maintained as tasks (of type ScheduledFuture) that are returned from the
various schedule methods. These tasks contain computations and report
back status and results. Thus, if an inner computation throws
an exception, the task's get() method will in turn throw it if
probed via get().

Because these kinds of exceptions are contained, the executor should not
and does not see them -- afterExecute should/does see only any
exceptions that the containing task itself throws.

So, if you'd like to trap/log internal exceptions, the supported way
to do it is:

   ScheduledFuture<?> task =
     executor.schedule(new ExceptionRunnable(), 1, TimeUnit.SECONDS);
   try {
     task.get();
   } catch(ExecutionException ex) {
     ... do something with ex.getCause() ...
   }

Note: as of Mustang you will be able to override
the concrete task class (using ScheduledThreadPoolExecutor.decorateTask)
which would allow you to create one that rethrows an inner exception
so that afterExecute will see it, if that's what you really want to do.

Sorry again for the confusion.

(Note to self. Impose a one-hour minimum before replying
to bug report mail :-)


-Doug




More information about the Concurrency-interest mailing list