我正在尝试使用Java的ThreadPoolExecutor类来运行大量具有固定数量线程的重量级任务。每个任务都有很多地方,在这些地方可能会由于异常而失败。
ThreadPoolExecutor
我已经继承了子类,ThreadPoolExecutor并且重写了afterExecute应该提供运行任务时遇到的任何未捕获异常的方法。但是,我似乎无法使其工作。
afterExecute
例如:
public class ThreadPoolErrors extends ThreadPoolExecutor { public ThreadPoolErrors() { super( 1, // core threads 1, // max threads 1, // timeout TimeUnit.MINUTES, // timeout units new LinkedBlockingQueue<Runnable>() // work queue ); } protected void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); if(t != null) { System.out.println("Got an error: " + t); } else { System.out.println("Everything's fine--situation normal!"); } } public static void main( String [] args) { ThreadPoolErrors threadPool = new ThreadPoolErrors(); threadPool.submit( new Runnable() { public void run() { throw new RuntimeException("Ouch! Got an error."); } } ); threadPool.shutdown(); } }
该程序的输出是“一切都很好-情况正常!” 即使唯一提交给线程池的Runnable引发异常。任何线索这里发生了什么?
谢谢!
提交Runnable时,它将被包装在Future中。
你的afterExecute应该是这样的:
public final class ExtendedExecutor extends ThreadPoolExecutor { // ... protected void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); if (t == null && r instanceof Future<?>) { try { Future<?> future = (Future<?>) r; if (future.isDone()) { future.get(); } } catch (CancellationException ce) { t = ce; } catch (ExecutionException ee) { t = ee.getCause(); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); } } if (t != null) { System.out.println(t); } } }