[转载]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 }

 

 

转载于:https://www.cnblogs.com/qrlozte/archive/2013/04/21/3034350.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值