1. 程式人生 > >帶日誌和計時等功能的執行緒池

帶日誌和計時等功能的執行緒池

帶日誌和計時等功能的執行緒池

歡迎關注作者部落格
簡書傳送門

前言

  我們先來聊聊ThreadPoolExecutor的拓展。

擴充套件ThreadPoolExecutor

  在執行任務的執行緒中將呼叫beforeExecute和afterExecute等方法,在這些方法中還可以新增日誌、計時、監視或者統計資訊收集的功能。無論任務是從run中正常返回,還是丟擲一個異常而返回,afterExecute都會被呼叫。如果任務在完成後帶有一個Error,那麼就不會呼叫afterExecute。如果beforeExecute丟擲一個RuntimeException,那麼任務將不被執行,並且afterExecute也不會被呼叫。

  線上程池完成關閉時呼叫terminated,也就是在所有任務都已經完成並且所有工作者執行緒也已經關閉後,terminated可以用來釋放Executor在其生命週期裡分配的各種資源,此外還可以執行傳送通知、記錄日誌或者手機finalize統計等操作。

  ThreadPoolExecutor使用了模板方法模式,提供了beforeExecute、afterExecute和terminated擴充套件方法。

  • 執行緒執行前呼叫beforeExecute(如果beforeExecute丟擲了一個RuntimeException,那麼任務將不會被執行)
  • 執行緒執行後呼叫afterExecute(丟擲異常也會呼叫,如果任務在完成後帶有一個Error,那麼就不會呼叫afterExecute)
  • 線上程池完成關閉操作時呼叫terminated,也就是所有任務都已經完成並且所有工作者執行緒也已經關閉後

原始碼

/**
 * @program:
 * @description: 具備日誌和計時等功能的執行緒池
 * @author: zhouzhixiang
 * @create: 2018-11-14 20:40
 */
public class TimingThreadPool extends ThreadPoolExecutor{
    private final ThreadLocal<Long> starttime = new ThreadLocal<
>(); private final AtomicLong numtask = new AtomicLong(); private final AtomicLong totaltime = new AtomicLong(); private final Logger logger = Logger.getLogger("TimingThreadPool"); public TimingThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); } @Override protected void beforeExecute(Thread t, Runnable r) { super.beforeExecute(t, r); logger.fine(String.format("Thread %s: start %s", t, r)); starttime.set(System.nanoTime()); } @Override protected void afterExecute(Runnable r, Throwable t) { try { long endtime = System.nanoTime() - starttime.get(); totaltime.addAndGet(endtime); numtask.incrementAndGet(); logger.fine(String.format("Thread %s: end %s, time=%dns", t, r, totaltime)); }finally { super.afterExecute(r, t); } } @Override protected void terminated() { try{ logger.info(String.format("Terminated: avg time=%dns", totaltime.get() / numtask.get())); }finally { super.terminated(); } } }

歡迎加入Java猿社群
歡迎加入Java猿社群.png