[转载]ScheduledThreadPoolExecutor and exception handling
1. Original Question: https://forums.oracle.com/forums/thread.jspa?threadID=1142455
Hi All,
i'm using ScheduledThreadPoolExecutor (with jdk 1.5) and I'm 
wondering about exception handling. My first goal is to handle the exceptions 
thrown by my Runnable task during its executions. I tried doing my ThreadFactory 
in order to add an Thread.UncaughtExceptionHandler to all created threads. This 
doesn't work because the exception is always caught by the FutureTask (see 
FutureTask$Sync.innerRun()) so my handler is never called. 
I tried doing 
my Executor:
1 public class MyExecutor extends ScheduledThreadPoolExecutor { 2 3 private Thread.UncaughtExceptionHandler exceptionHandler = null; 4 5 MyExecutor (int maxThreadPoolSize, 6 Thread.UncaughtExceptionHandler exceptionHandler) { 7 super(maxThreadPoolSize); 8 this.exceptionHandler = exceptionHandler; 9 } 10 11 MyExecutor (int maxThreadPoolSize, 12 ThreadFactory threadFactory, 13 Thread.UncaughtExceptionHandler exceptionHandler) { 14 super(maxThreadPoolSize, threadFactory); 15 this.exceptionHandler = exceptionHandler; 16 } 17 18 @Override 19 protected void afterExecute(Runnable r, Throwable t) { 20 super.afterExecute(r, t); 21 if (r instanceof Future<?>) { 22 try { 23 if (((Future<?>) r).isDone()) { 24 Object result = ((Future<?>) r).get(); 25 } 26 } catch (InterruptedException ie) { 27 } catch (ExecutionException ee) { 28 Throwable realThrowable = ee.getCause(); 29 MyException e = new MyException (realThrowable); 30 exceptionHandler.uncaughtException(Thread.currentThread(), e); 31 } catch (CancellationException ce) { 32 } 33 } 34 } 35 }
and it seems to work fine. 
What do you think about that ?
Done  this, my second goal is to re-schedule a task that threw an exception.
Has anyone has an idea ? 
A thing I could do is to re-schedule the  task in my exception handling, but in that method I don't have any reference to  my Runnable object; I have just a ScheduledFuture but I didn't find a way to get  my Runnable object and I need a reference to my object because I have different  objects run and without that infomation I don't know what to re-schedule. 
 Can any body shed light on it?
Thanks a lot  Stefano
Re: ScheduledThreadPoolExecutor and exception handling
There is always an issue with granularity when it comes to uncaught exceptions. 
The UncaughtExceptionHandler acts at the Thread-level such that if the Thread's 
run() method terminates due to an exception then the UEH is called. However 
there is no mechanism for dealing with uncaught exceptions at the level of 
Runnable's. As you discovered FutureTask never lets exceptions escape so the UEH 
never comes into play.
One way to deal with it is as you have by 
subclassing ScheduledThreadPoolExecutor and using afterExecute to see if you 
have a Future and call Future.get which will throw the exception. It is a bit 
kludgy to force the exception to be thrown and immediately catch it but you 
don't have a choice.
The other option is use a concrete Runnable class 
that encapsulates the real Runnable so that it catches all exceptions - that way 
the FutureTask never gets them. I prefer this way if you can control submission 
to the executor. This way also allows you to re-submit to the executor more 
easily - otherwise you have to maintain the association between Runnables and 
FutureTasks yourself.
2. Original Question: http://stackoverflow.com/questions/3875739/exception-handling-in-threadpools/3875784#3875784
Solution 1:
Decorator pattern, for example:
1 public class CatcherRunnable implements Runnable { 2 private Runnable runMe; 3 4 public CatcherRunnable(Runnable runMe) { 5 this.runMe = runMe; 6 } 7 8 public void run() { 9 try { 10 runMe.run(); 11 } catch (Exception ex){ 12 ex.printStackTrace(); 13 } 14 } 15 }
Wrap all your Runnables with this CatcherRunnable.
Solution2: (doesn't work with ScheduledThreadPoolExecutor)
Provide this factory to the Executor you use.
1 private static class ExceptionCatchingThreadFactory implements ThreadFactory { 2 private final ThreadFactory delegate; 3 4 private ExceptionCatchingThreadFactory(ThreadFactory delegate) { 5 this.delegate = delegate; 6 } 7 8 public Thread newThread(final Runnable r) { 9 Thread t = delegate.newThread(r); 10 t.setUncaughtExceptionHandler(new UncaughtExceptionHandler() { 11 @Override 12 public void uncaughtException(Thread t, Throwable e) { 13 e.printStackTrace(); //replace with your handling logic. 14 } 15 }); 16 return t; 17 } 18 }
 
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号