ThreadPoolExecutor钩子函数beforeExecute、afterExecute不要抛出异常,否则会导致线程退出
ThreadPoolExecutor为我们提供了两个比较好的钩子函数:beforeExecute、afterExecute ,我们可以重写这两个方法,做一些初始化、资源清理、打印日志、线程池监控等之类的工作。
比如线程池监控的例子:https://zditect.com/code/java/java-thread-pool-monitoring.html
但是,我们必须注意一点,我们重写的这两个钩子函数中必须自己处理他们可能抛出的异常情况,否则,这两个钩子函数向线程池抛出异常,会导致线程退出,线程池中的线程数目减少,不能达到重复利用的效果,失去了线程池的意义。
我们以源码来分析:
在任务执行过程中,会在任务执行前调用beforeExecute 方法,在任务执行后调用afterExecute方法。如果抛出异常,会导致while循环退出,Worker 终止从任务队列中获取任务,线程退出,并且,执行
java.util.concurrent.ThreadPoolExecutor#processWorkerExit
做一些清理工作。
而抛出的异常,是否能被我们感知,其结论与
Java避坑指南:ThreadPoolExecutor提交任务出现异常,异常是否吞掉,线程是否退出的不同影响
一致。
小结
ThreadPoolExecutor钩子函数beforeExecute、afterExecute一定要自己处理 异常,禁止再向线程池抛出,否则会导致线程退出,而且异常信息不会被记录在日志系统里,或许导致报警报不出问题。