1、无论任务是从run中正常返回,还是抛出一个异常而返回,afterExecute都会被调用。如果任务在完成后带有一个Error,那么就不会盗用afterExecute。
2、如果beforeExecute抛出一个RuntimeException,那么任务将不被执行,afterExecute也会被调用。
3、在线程完成关闭操作时调用terminated,也就是在所有任务都已经完成并且所有工作者线程也已经关闭后。terminated可以用来释放Executor在其生命周期里分配的各种资源,此外还可以执行发送通知、记录日志或者手机finalize统计信息等操作。
4、代码示例如下:
/** * Copyright (C),MZJ<br> * <p> * 线程池扩展 * * @author muzhongjiang 2015年3月10日 */ @Log4j2 public class MyThreadPool extends ThreadPoolExecutor { private static final int DEFAULT_CORE_POOL_SIZE = 2; private static final int DEFAULT_MAXIMUM_POOL_SIZE = 4; private static final long DEFAULT_KEEP_ALIVE_TIME = 30L;//秒 private static final TimeUnit DEFAULT_UNIT = TimeUnit.SECONDS;//秒 private static final BlockingQueue<Runnable> DEFAULT_WORK_QUEUE = new LinkedBlockingQueue<>(1024); public MyThreadPool() { super(DEFAULT_CORE_POOL_SIZE, DEFAULT_MAXIMUM_POOL_SIZE, DEFAULT_KEEP_ALIVE_TIME, DEFAULT_UNIT, DEFAULT_WORK_QUEUE); } public MyThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue ) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); } private final ThreadLocal<Long> startTime = new ThreadLocal<Long>(); private final AtomicLong numTasks = new AtomicLong(); private final AtomicLong totalTime = new AtomicLong(); @Override protected void beforeExecute(Thread t, Runnable r) { super.beforeExecute(t, r); log.info(String.format("执行beforeExecute方法>>> %s: start %s", t, r)); startTime.set(System.nanoTime()); } @Override protected void afterExecute(Runnable r, Throwable t) { try { long endTime = System.nanoTime(); long taskTime = endTime - startTime.get(); numTasks.incrementAndGet(); totalTime.addAndGet(taskTime); log.info(String.format("执行afterExecute方法>>> %s: end %s, time=%dns", t, r, taskTime)); } finally { super.afterExecute(r, t); } } @Override protected void terminated() { try { log.info(String.format("Terminated方法: avg time=%dns", totalTime.get() / numTasks.get())); } finally { super.terminated(); } } public static void main(String[] args) { ThreadPoolExecutor threadPoolExecutor = new MyThreadPool(); // threadPoolExecutor.submit(() -> 1 / 0); threadPoolExecutor.submit(() -> System.out.println("hello world")); threadPoolExecutor.shutdown(); } }