zoukankan      html  css  js  c++  java
  • [转载]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 }
  • 相关阅读:
    JSP一个简单的项目实现教程
    多个Excel文件快速导入到DB里面
    NotePad++左侧导航
    简单实用JSTL标签库
    Eclipse导入现有项目
    Java工具Eclipse
    winform窗体只能放大不能缩小
    ref out

    数组
  • 原文地址:https://www.cnblogs.com/qrlozte/p/3034350.html
Copyright © 2011-2022 走看看