[concurrency-interest] ScheduledThreadPoolExecutor lost exception?

TAlison at ameritrade.com TAlison at ameritrade.com
Tue May 24 16:12:36 EDT 2005


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.
 
Example:
 
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
 
public class SchedulerExample extends ScheduledThreadPoolExecutor
{
 
    public SchedulerExample(int threads)
    {
        super(threads);
    }
 
    /**
     * @param args
     */
    public static void main(String[] args)
    {
        ScheduledExecutorService executor = new SchedulerExample(5);
        executor.schedule(new ExceptionRunnable(), 1, TimeUnit.SECONDS);
    }
 
    static class ExceptionRunnable implements Runnable
    {
        public void run()
        {
            System.out.println("Throwing a runtime exception.");
            String npe = null;
            System.out.println(npe.toString() + ": Null pointer
exception should have been thrown.");
        }
    }
 
    @Override
    protected void afterExecute(Runnable r, Throwable t)
    {
        super.afterExecute(r, t);
 
        System.out.println("Executing afterExecute. Throwable is " + t);
        if (t != null)
            t.printStackTrace();
    }
}




More information about the Concurrency-interest mailing list