ThreadPoolExecutor是可扩展的,其提供了几个可在子类化中改写的方法,如下:

  1. protected void beforeExecute(Thread t, Runnable r) { }
  2. protected void afterExecute(Runnable r, Throwable t) { }
  3. protected void terminated() { }

  现基于此,完成一个统计每个线程执行耗时,并计算平均耗时的 自定义线程池样例。通过 beforeExecute、afterExecute、terminated 方法来添加日志记录和统计信息收集。为了测量任务的运行时间,beforeExecute必须记录开始时间并把它保存到一个ThreadLocal变量中,然后由afterExecute来读取。同时,使用两个 AtomicLong变量,分别用以记录已处理的任务数和总的处理时间,并通过terminated来输出包含平均任务时间的日志消息。

  自定义线程池代码如下:

  1. import java.util.concurrent.BlockingQueue;
  2. import java.util.concurrent.ThreadPoolExecutor;
  3. import java.util.concurrent.TimeUnit;
  4. import java.util.concurrent.atomic.AtomicLong;
  5. import java.util.logging.Logger;
  6.  
  7. /**
  8. * 自定义线程池
  9. */
  10. public class TimingThreadPool extends ThreadPoolExecutor {
  11.  
  12. private final ThreadLocal<Long> startTime = new ThreadLocal<>();
  13. private final Logger log = Logger.getLogger("TimingThreadPool");
  14. private final AtomicLong numTasks = new AtomicLong();
  15. private final AtomicLong totalTime = new AtomicLong();
  16.  
  17. public TimingThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
  18. super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
  19. }
  20.  
  21. @Override
  22. protected void beforeExecute(Thread t, Runnable r) {
  23. super.beforeExecute(t, r);
  24. log.info(String.format("Thread %s: start %s",t,r));
  25. startTime.set(System.nanoTime());
  26. }
  27.  
  28. @Override
  29. protected void afterExecute(Runnable r, Throwable t) {
  30. try {
  31. long endTime = System.nanoTime();
  32. long taskTime = endTime - startTime.get();
  33. numTasks.incrementAndGet();
  34. totalTime.addAndGet(taskTime);
  35. log.info(String.format("Thread %s: end %s, time=%dns",t,r,taskTime));
  36.  
  37. } finally {
  38. super.afterExecute(r,t);
  39. }
  40. }
  41.  
  42. @Override
  43. protected void terminated() {
  44. try {
  45. log.info(String.format("Terminated: avg time=%dns",totalTime.get() / numTasks.get()));
  46. } finally {
  47. super.terminated();
  48. }
  49. }
  50. }

  测试执行效果代码如下:

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import java.util.concurrent.Callable;
  4. import java.util.concurrent.Future;
  5. import java.util.concurrent.LinkedBlockingQueue;
  6. import java.util.concurrent.TimeUnit;
  7.  
  8. /**
  9. * 测试自定义线程池
  10. */
  11. public class TestCustomThreadPool {
  12.  
  13. public static void main(String[] args) {
  14.  
  15. try {
  16. TimingThreadPool threadPool = new TimingThreadPool(,,0L, TimeUnit.MILLISECONDS,
  17. new LinkedBlockingQueue<Runnable>());
  18.  
  19. List<TestCallable> tasks = new ArrayList<>();
  20.  
  21. for (int i = ; i < ; i++) {
  22. tasks.add(new TestCallable());
  23. }
  24.  
  25. List<Future<Long>> futures = threadPool.invokeAll(tasks);
  26. for (Future<Long> future :
  27. futures) {
  28. System.out.print(" - "+future.get());
  29. }
  30. threadPool.shutdown();
  31.  
  32. } catch (Exception e) {
  33. e.printStackTrace();
  34. }
  35.  
  36. }
  37.  
  38. static class TestCallable implements Callable<java.lang.Long> {
  39.  
  40. @Override
  41. public Long call() throws Exception {
  42. long total = ;
  43. for (int i = ; i < ; i++) {
  44. long now = getRandom();
  45. total += now;
  46. }
  47. Thread.sleep(total);
  48. return total;
  49. }
  50.  
  51. public long getRandom () {
  52. return Math.round(Math.random() * );
  53. }
  54. }
  55.  
  56. }

执行结果:

Java自定义线程池-记录每个线程执行耗时的更多相关文章

  1. Java如何判断线程池所有任务是否执行完毕

    import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Tes ...

  2. Java 线程池记录

    Java通过Executors提供四种线程池,分别为:newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程.newFixe ...

  3. Java多线程系列--“JUC线程池”03之 线程池原理(二)

    概要 在前面一章"Java多线程系列--“JUC线程池”02之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包括:线程池示例参考代 ...

  4. Java多线程系列--“JUC线程池”04之 线程池原理(三)

    转载请注明出处:http://www.cnblogs.com/skywang12345/p/3509960.html 本章介绍线程池的生命周期.在"Java多线程系列--“基础篇”01之 基 ...

  5. Java线程池二:线程池原理

    最近精读Netty源码,读到NioEventLoop部分的时候,发现对Java线程&线程池有些概念还有困惑, 所以深入总结一下 Java线程池一:线程基础 为什么需要使用线程池 Java线程映 ...

  6. Java多线程系列--“JUC线程池”01之 线程池架构

    概要 前面分别介绍了"Java多线程基础"."JUC原子类"和"JUC锁".本章介绍JUC的最后一部分的内容——线程池.内容包括:线程池架构 ...

  7. Java多线程系列--“JUC线程池”02之 线程池原理(一)

    概要 在上一章"Java多线程系列--“JUC线程池”01之 线程池架构"中,我们了解了线程池的架构.线程池的实现类是ThreadPoolExecutor类.本章,我们通过分析Th ...

  8. Java多线程系列--“JUC线程池”05之 线程池原理(四)

    概要 本章介绍线程池的拒绝策略.内容包括:拒绝策略介绍拒绝策略对比和示例 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3512947.html 拒绝策略 ...

  9. 深入浅出 Java Concurrency (34): 线程池 part 7 线程池的实现及原理 (2)[转]

    线程池任务执行流程 我们从一个API开始接触Executor是如何处理任务队列的. java.util.concurrent.Executor.execute(Runnable) Executes t ...

随机推荐

  1. NLTK 第一篇:介绍

    NLTK(Natural Language Toolkit)是一个功能强大的自然语言处理工具,它提供了一组自然语言算法,例如切分词(Tokenize),词性标注(Part-Of-Speech Tagg ...

  2. Python从菜鸟到高手(8):print函数、赋值与代码块

    1.神奇的print函数   print函数相信读者一定对它不陌生,因为在前面的章节,几乎每个例子都使用了print函数,这个函数的功能就是在控制台输出文本.不过print在输出文本时还可以进行一些设 ...

  3. C#(.NET) HMAC SHA256实现

    HMAC SHA256的实现比较简单,可以用多种语言实现,下面我用C#语言实现,一种结果是居于BASE64,另外一种是居于64位. C# HMAC SHA256 (Base64) using Syst ...

  4. eclipse 常用配置

    一.内置tomcat配置 解决eclipse 内置tomcat 与本地tomcat 端口冲突 传送门:http://www.cnblogs.com/tweet/p/7568979.html 二.字体设 ...

  5. tensorflow-gpu安装的一些注意

    按正确的顺序安装,严格安装特定的版本 1,下载和安装严格版本的cuda和cuDnn,其他版本的不干活.比如要求9.0你就不能装9.1.https://www.tensorflow.org/instal ...

  6. [蛙蛙推荐]SICP第一章学习笔记-编程入门

    本书简介 <计算机程序的构造与解释>这本书是MIT计算机科学学科的入门课程, 大部分学生在学这门课程前都没有接触过程序设计,也就是说这本书是针对编程新手写的. 虽然是入门课程,但起点比较高 ...

  7. 根据指定条件使CheckBox 无法选中

    var trList = $("#tab1").children("tr")for (var i=0;i<trList.length;i++) {var ...

  8. shell 读取配置文件的方法

    原文地址:http://bbs.chinaunix.net/thread-3628456-1-1.html 总结地址:https://www.cnblogs.com/binbinjx/p/568021 ...

  9. Dapper-小型ORM之王(C#.NET)

    ORM:对象关系映射器,它直接将数据库映射到C#对象. 有很多ORM框架可用,Dapper是其中之一,被称为ORM之王. 下面是Dapper主要的一些功能: 速度快,性能好; 更少的代码行 对象映射 ...

  10. Python_%---format_43

    fat39 博客园 首页 新随笔 联系 订阅 管理 随笔 - 142  文章 - 0  评论 - 0 python基础_格式化输出(%用法和format用法)   目录 %用法 format用法 %用 ...