java.util.concurrent 包中包含灵活的线程池实现,但是更重要的是,它包含用于管理实现 Runnable 的任务的执行的整个框架,该框架称为 Executor 框架。该框架基于生产者-消费者模式,提交任务的操作相当于生产者,执行任务的线程则是相当于消费者。其类图结构:

ThreadPoolExecutor是可以扩展的,它提供了几个可以在子类中可扩展的方法:beforeExecute 、afterExecute、terminated。无论任务是从run中正常返回还是抛出一个异常,afterExecute都会被调用[如果任务在完成后带有一个Error,那么就不会调用afterExecute]。如果抛出一个RuntimeException,那么任务将不被执行,并且afterExecute也不会被调用。在线程池完成关闭时调用terminated,也就是在所有的任务都已经完成并且所有工作者线程也已经关闭后。

public class JHThreadPoolExecutor extends ThreadPoolExecutor {

    // 记录每个线程执行任务开始时间
private ThreadLocal<Long> start = new ThreadLocal<Long>(); // 记录所有任务完成使用的时间
private AtomicLong totals = new AtomicLong(); // 记录线程池完成的任务数
private AtomicInteger tasks = new AtomicInteger(); public JHThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
} public JHThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
} public JHThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
} public JHThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
} /**
* 每个线程在调用run方法之前调用该方法
* */
protected void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r);
start.set(System.currentTimeMillis());
} /**
* 每个线程在执行完run方法后调用该方法
* */
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
tasks.incrementAndGet();
totals.addAndGet(System.currentTimeMillis() - start.get());
} @Override
protected void terminated() {
super.terminated();
System.out.println("[THREADPOOL]完成"+ tasks.get() +"个任务,平均耗时:" + totals.get() / tasks.get() + ".ms");
} } public class Task implements Runnable { @Override
public void run() {
try {
TimeUnit.SECONDS.sleep(5);
} catch (Exception e) {
System.err.println(e.getMessage());
}
} } public class Main { public static void main(String []args) {
BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
JHThreadPoolExecutor executor = new JHThreadPoolExecutor(3, 5, 5, TimeUnit.MINUTES, queue);
for(int i = 0 ; i < 5 ; ++i) {
executor.submit(new Task());
}
executor.shutdown();
} }

上述结果输出:

[THREADPOOL]完成5个任务,平均耗时:5001.ms

Java Executor框架的更多相关文章

  1. Java Executor 框架

    Java Executor 框架 Executor框架是指java5中引入的一系列并发库中与executor相关的功能类,包括Executor.Executors. ExecutorService.C ...

  2. Java Executor框架使用

    Java Executor框架是Jdk1.5之后推出的,是为了更加方便的开发多线程应用而封装的框架: 相比传统的Thread类,Java Executor使用方便,性能更好,更易于管理,而且支持线程池 ...

  3. 使用Java Executor框架实现多线程

    本文将涵盖两个主题: 通过实现Callable接口创建线程 在Java中使用Executor框架 实现Callable接口 为了创建一段可以在线程中运行的代码,我们创建了一个类,然后实现了Callab ...

  4. Java Executor 框架学习总结

    大多数并发都是通过任务执行的方式来实现的.一般有两种方式执行任务:串行和并行. class SingleThreadWebServer { public static void main(String ...

  5. java并发编程(十七)Executor框架和线程池

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17465497   Executor框架简介 在Java 5之后,并发编程引入了一堆新的启动 ...

  6. Java并发和多线程(二)Executor框架

    Executor框架 1.Task?Thread? 很多人在学习多线程这部分知识的时候,容易搞混两个概念:任务(task)和线程(thread). 并发编程可以使我们的程序可以划分为多个分离的.独立运 ...

  7. java并发编程-Executor框架

    Executor框架是指java 5中引入的一系列并发库中与executor相关的一些功能类,其中包括线程池,Executor,Executors,ExecutorService,Completion ...

  8. Java并发——线程池Executor框架

    线程池 无限制的创建线程 若采用"为每个任务分配一个线程"的方式会存在一些缺陷,尤其是当需要创建大量线程时: 线程生命周期的开销非常高 资源消耗 稳定性 引入线程池 任务是一组逻辑 ...

  9. JAVA的Executor框架

    Executor框架分离了任务的创建和执行.JAVA SE5的java.util.concurrent包中的执行器(Executor)管理Thread对象,从而简化了并发编程.Executor引入了一 ...

随机推荐

  1. 【 Linux 】Linux套接字简要说明

    Linux套接字    源IP地址和目的IP地址以及源端口和目标端口号的组合称为套接字.其作用于标识客户端请求的服务器和服务. 套接字,支持TCP/IP的网络通信的基本操作单元,可以看做是不同主机之间 ...

  2. 区块链开发(四)Nodejs下载&安装

    以太坊框架truffle的安装需要依赖nodejs中的npm命令,本篇博客我们就简单介绍一下node的安装过程.操作系统基于ubuntu 16.04版本. 下载地址 nodejs官网:http://w ...

  3. 如何理解reliability

    首先推荐看: https://wenku.baidu.com/view/f55f400c52ea551810a68746.html 复习一下均值方差 然后重点看: https://www.social ...

  4. 在使用Arduino中遇到的问题(无法使用中文注释、程序无法下载)

    在使用Arduino中遇到的问题: 在用arduino给蓝牙模块供电时,下载程序是下不进去的.即使显示下进去了,其实也是没下进去. 解决方法:拔掉蓝牙模块再下程序,或给蓝牙供电的线上加上一个开关. 在 ...

  5. set注入

    顾名思义set注入必须要有set方法. 基本类型的注入.引用类型注入.List注入.Set注入.Map注入.Properties注入 public class person { private car ...

  6. int 与 String 与 char 之间的互相转换

    int 转 String: //方式一: int i1 = 888; String s1 = Integer.toString(i1); //方式二: int i2 = 888; String s2 ...

  7. (1)python Scrapy爬虫框架

    部署 1.安装python3.6  64bit 2.下载pywin32 https://sourceforge.net/projects/pywin32/files/pywin32/ 双击安装 3.下 ...

  8. python 执行顺序

    从上往下顺序执行,定义的方法和类要写在调用之前, 如果有 if __name__ == '__main__'   改方法所在的文件作为启动文件时会被调用,如果作为模块被调用时不会被执行.

  9. HDU 1686 Oulipo【kmp求子串出现的次数】

    The French author Georges Perec (1936–1982) once wrote a book, La disparition, without the letter 'e ...

  10. 洛谷P1095 绝地武士的逃离

    好吧原题是守望者的逃离,我强行改了一波题面,因为信仰=-=(? May the force be with us. 绝地跑步速度为17m/s,但无法逃离荒岛.绝地的原力恢复速度为4点/s,只有处在原地 ...