ThreadPools中的exception处理

我有一个ScheduledThreadPoolExecutor似乎在吃exception。 如果提交的Runnable引发exception,我希望执行程序服务通知我。

例如,我想下面的代码至less打印IndexArrayOutOfBoundsException的stackTrace

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

作为一个侧面的问题。 有没有办法为ScheduledThreadPoolExecutor编写一个通用的try catch块?

//////////原文问题结束//////////////

正如所build议的,以下装饰工程运作良好。

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

我刚才写了一个关于这个问题的小贴子 。 你有两个select:

  1. 使用Colin Herbert提供的解决scheme
  2. 使用Mark Peters 解决scheme的修改版本,而不是分配UncaughtExceptionHandler而是将每个提交的runnable包装到您自己的runnable中,在try-catch-block中执行(调用run )真正的runnable。

编辑
正如Mark指出的那样,将传递给ScheduledExecutorServiceRunnable而不是传递给ThreadFactoryRunnable包装起来非常重要。

警告 :此方法不适用于预定的线程池执行程序。 这个答案与其他线程池执行者的相关性已经被取消了。 看威利的答案 。

重写ThreadFactory为Thread提供一个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; } } 

您可以通过调用scheduleAtFixedRate()来使用Futureget()方法。 如果在线程执行过程中发生怀疑,它将抛出ExecutionExceptionexception。

你也可以使用Spring框架中的ThreadPoolTaskScheduler ,它提供了一个设置error handling器的方法,并为你做了所有的包装。 默认行为取决于任务的types:

如果提供的ErrorHandler不为空,它将被使用。 否则,默认情况下,重复任务将被错误抑制,而一次性任务会默认传播错误,因为这些错误可能是通过返回的Future来预期的。 在这两种情况下,都会logging错误。

如果你只想使用包装部分,而不是你可以使用的TaskScheduler

 TaskUtils.decorateTaskWithErrorHandler(task, errorHandler, isRepeatingTask) 

TaskScheduler内部使用。

您可以对ScheduledThreadPoolExecutor进行子类化,并重写afterExecute方法来处理您提交的任何types的Runnable的exception和错误。

考虑在您的ScheduledThreadPoolExecutor类中添加一个静态事件,以便在引发exception时调用您的任何任务。 这样,您可以利用该事件来捕获和处理线程中发生的exception。