线程池中的异常处理

2022-09-01 01:37:26

我有一个 ScheduledThreadPoolExecutor,它似乎正在吃异常。我希望我的执行器服务在提交的 Runnable 引发异常时通知我。

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

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

作为题外话。有没有办法为 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();
        }
    }
}

答案 1

不久前,我写了一篇关于这个问题的小文章。您有两种选择:

  1. 使用 Colin Herbert 提供的解决方案,或者
  2. 使用Mark Peters解决方案的修改版本,但不是分配一个你将每个提交的可运行包到你自己的可运行中,该可运行项在尝试捕获块内执行(调用)真正的可运行。UncaughtExceptionHandlerrun

编辑
正如 Mark 所指出的,重要的是将传递到的包装,而不是传递给 .RunnableScheduledExecutorServiceThreadFactory


答案 2

警告:此方法不适用于定时线程池执行程序。此答案已取消删除,因为它与其他线程池执行程序相关。看看威利的答案

覆盖 为 Threads 提供一个 UncaughtExceptionHandler:ThreadFactory

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;
    }
}

推荐