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:
- 使用Colin Herbert提供的解决scheme
-  使用Mark Peters 解决scheme的修改版本,而不是分配UncaughtExceptionHandler而是将每个提交的runnable包装到您自己的runnable中,在try-catch-block中执行(调用run)真正的runnable。
  编辑 
 正如Mark指出的那样,将传递给ScheduledExecutorService的Runnable而不是传递给ThreadFactory的Runnable包装起来非常重要。 
警告 :此方法不适用于预定的线程池执行程序。 这个答案与其他线程池执行者的相关性已经被取消了。 看威利的答案 。
 重写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()来使用Future的get()方法。 如果在线程执行过程中发生怀疑,它将抛出ExecutionExceptionexception。 
 你也可以使用Spring框架中的ThreadPoolTaskScheduler ,它提供了一个设置error handling器的方法,并为你做了所有的包装。 默认行为取决于任务的types: 
  如果提供的ErrorHandler不为空,它将被使用。  否则,默认情况下,重复任务将被错误抑制,而一次性任务会默认传播错误,因为这些错误可能是通过返回的Future来预期的。  在这两种情况下,都会logging错误。 
 如果你只想使用包装部分,而不是你可以使用的TaskScheduler 
 TaskUtils.decorateTaskWithErrorHandler(task, errorHandler, isRepeatingTask) 
  TaskScheduler内部使用。 
您可以对ScheduledThreadPoolExecutor进行子类化,并重写afterExecute方法来处理您提交的任何types的Runnable的exception和错误。
考虑在您的ScheduledThreadPoolExecutor类中添加一个静态事件,以便在引发exception时调用您的任何任务。 这样,您可以利用该事件来捕获和处理线程中发生的exception。