ThreadPools中的异常处理

Iva*_*van 42 java exception-handling threadpool

我有一个ScheduledThreadPoolExecutor似乎正在吃Exception.如果提交的Runnable抛出异常,我希望我的执行程序服务通知我.

例如,我希望下面的代码至少打印出IndexArrayOutOfBoundsException的stackTrace

threadPool.scheduleAtFixedRate(
  new Runnable() {
    public void run() {
      int[] array = new array[0];
      array[42] = 5;
    }
  },
  1000,
  1500L,
  TimeUnit.MILLISECONDS);
Run Code Online (Sandbox Code Playgroud)

作为一个附带问题.有没有办法为ScheduledThreadPoolExecutor编写一般的try catch块?

//////////原始问题的结尾//////////////

正如所建议的那样,以下装饰器运行良好

public class CatcherTask implements Runnable{

    Runnable runMe;

    public CatcherTask(Runnable runMe) {
        this.runMe = runMe;
    }

    public void run() {
        try {
            runMe.run();
        } catch (Exception ex){
            ex.printStackTrace();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

whi*_*rra 24

我刚才写了一篇关于这个问题的小帖子.您有两种选择:

  1. 使用Colin Herbert提供的解决方案
  2. 使用Mark Peters 解决方案的修改版本,而不是指定UncaughtExceptionHandler将每个提交的runnable包装到您自己的runnable中,该runnable执行(调用run)try-catch-block中的真实runnable.

编辑
正如马克指出的那样,将Runnable传递的内容包装起来ScheduledExecutorService而不是传递给传递的内容是很重要的ThreadFactory.

  • 实际上我尝试了你的#2并且无法让它工作.在委托Runnable中,异常被捕获到了我的try/catch块之上,所以这似乎与UncaughtExceptionHandler一样陷入了同样的问题. (2认同)

Mar*_*ers 13

警告:此方法不适用于计划的线程池执行程序.这个答案因其与其他线程池执行程序的相关性而未被删除.见威利的答案.

重写ThreadFactory以给Threads一个UncaughtExceptionHandler:

ThreadPoolExecutor exec = new ThreadPoolExecutor...;

exec.setThreadFactory(new ExceptionCatchingThreadFactory(exec.getThreadFactory()));
//go on to submit tasks...


private static class ExceptionCatchingThreadFactory implements ThreadFactory {
    private final ThreadFactory delegate;

    private ExceptionCatchingThreadFactory(ThreadFactory delegate) {
        this.delegate = delegate;
    }

    public Thread newThread(final Runnable r) {
        Thread t = delegate.newThread(r);
        t.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread t, Throwable e) {
                e.printStackTrace();  //replace with your handling logic.
            }
        });
        return t;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • `uncaughExceptionHandler`不适用于预定的runnables. (4认同)

Col*_*ert 5

您可以通过调用使用您获得的get()方法.如果在线程执行期间发生了异常,它将抛出一个.FuturescheduleAtFixedRate()ExecutionException