ThreadPoolExecutor类提供了三个Hook methods,这三个方法一般用作被子类重写:
protected void beforeExecute(Thread t, Runnable r) { } protected void afterExecute(Runnable r, Throwable t) { } protected void terminated() { }
beforeExecute和afterExecute这两个方法在每个任务执行前后被调用,可以用来更新执行环境,例如,重新初始化ThreadLocals,收集统计信息,或者添加日志信息!
terminated在Executor终止时调用,默认实现不执行任何操作,子类通常应在此方法内调用{@code super.terminated}。
注意:如果钩子(回调方法)引发异常,内部工作线程可能进而失败并突然终止。
beforeExecute:
在给定线程中执行给定Runnable之前调用的方法。 这个方法由执行任务的线程调用,可用于重新初始化ThreadLocals或更新日志记录。默认实现不执行任何操作,但可以在子类中对其进行自定义。
注意:子类通常应在此方法的末尾调用{@code super.beforeExecute}。
afterExecute:
在给定线程中执行给定Runnable完成时调用的方法。这个方法由执行任务的线程调用。如果Throwable非null,则Throwable是导致执行突然终止的未捕获{@code RuntimeException}或{@code Error}。默认实现不执行任何操作,但可以在子类中对其进行自定义。
注意:子类通常应在此方法的开头调用{@code super.afterExecute}。
package concurrent.threadpool; import java.util.concurrent.*; public class Hook { public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService exec = new ThreadPoolExecutor(1, 1, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>()) { @Override protected void terminated() { System.out.println("Executor Has Terminated!"); } @Override protected void beforeExecute(Thread t, Runnable r) { System.out.println("before!"); super.beforeExecute(t, r); } @Override protected void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); if (t == null && r instanceof Future<?>) { try { Object result = ((Future<?>) r).get(); } catch (CancellationException ce) { t = ce; } catch (ExecutionException ee) { t = ee.getCause(); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); // ignore/reset } } if (t != null) { System.out.println(t); } } }; for (int i = 0; i < 2; i++) { exec.submit(new Runnable() { @Override public void run() { System.out.println("Running...!"); } }); } exec.submit(new Callable<Integer>() { @Override public Integer call() throws Exception { return 100; } }); exec.shutdown(); } }