ThreadPoolExecutor是可扩展的,下面一个示例:

package com.dxz.threadpool.demo1;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong; public class StatThreadPoolExecutor extends ThreadPoolExecutor { private final ThreadLocal<Long> startTime = new ThreadLocal<Long>();
private final AtomicLong numTasks = new AtomicLong();
private final AtomicLong totalTime = new AtomicLong(); public StatThreadPoolExecutor(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);
System.out.println(String.format("beforeExecute() Thread '%s': start '%s'", t, r));
startTime.set(System.nanoTime());
} @Override
protected void afterExecute(Runnable r, Throwable t) {
try {
long endTime = System.nanoTime();
long taskTime = endTime - startTime.get();
numTasks.incrementAndGet();
totalTime.addAndGet(taskTime);
System.out.println(String.format("afterExecute() : end '%s', time=%dns", r, taskTime));
} finally {
super.afterExecute(r, t);
}
} @Override
protected void terminated() {
try {
System.out.println(String.format("terminated() Terminated: avg time=%dns", totalTime.get() / numTasks.get()));
} finally {
super.terminated();
}
}
}

启动程序:

package com.dxz.threadpool.demo1;

import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; public class StatClient {
public static void main(String[] args) {
ThreadPoolExecutor exec = new StatThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
exec.execute(new Thread(new Printer(5),"t5"));
exec.execute(new Thread(new Printer(4),"t4"));
exec.execute(new Thread(new Printer(3),"t3"));
exec.execute(new Thread(new Printer(2),"t2"));
exec.execute(new Thread(new Printer(1),"t1"));
exec.shutdown();
} } class Printer implements Runnable {
private int sleepTime; public Printer(int sleepTime) {
this.sleepTime = sleepTime;
} @Override
public void run() {
System.out.println(Thread.currentThread().getName() + " is running.");
try {
TimeUnit.SECONDS.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
} }

结果:

beforeExecute() Thread 'Thread[pool-1-thread-5,5,main]': start 'Thread[t1,5,main]'
beforeExecute() Thread 'Thread[pool-1-thread-4,5,main]': start 'Thread[t2,5,main]'
beforeExecute() Thread 'Thread[pool-1-thread-1,5,main]': start 'Thread[t5,5,main]'
beforeExecute() Thread 'Thread[pool-1-thread-2,5,main]': start 'Thread[t4,5,main]'
beforeExecute() Thread 'Thread[pool-1-thread-3,5,main]': start 'Thread[t3,5,main]'
pool-1-thread-2 is running.
pool-1-thread-1 is running.
pool-1-thread-5 is running.
pool-1-thread-4 is running.
pool-1-thread-3 is running.
afterExecute() : end 'Thread[t1,5,main]', time=1001000273ns
afterExecute() : end 'Thread[t2,5,main]', time=2001157367ns
afterExecute() : end 'Thread[t3,5,main]', time=3000630301ns
afterExecute() : end 'Thread[t4,5,main]', time=4000804066ns
afterExecute() : end 'Thread[t5,5,main]', time=5001279195ns
terminated() Terminated: avg time=3000974240ns

可以看到,在测试类client中通过execute了五个线程,然后分别对这五个线程进行统计,最后统计出各个线程的耗时平均时间。

ThreadPoolExecutor之三:自定义线程池-扩展示例的更多相关文章

  1. 基于ThreadPoolExecutor,自定义线程池简单实现

    一.线程池作用 在上一篇随笔中有提到多线程具有同一时刻处理多个任务的特点,即并行工作,因此多线程的用途非常广泛,特别在性能优化上显得尤为重要.然而,多线程处理消耗的时间包括创建线程时间T1.工作时间T ...

  2. Android线程管理之ThreadPoolExecutor自定义线程池

    前言: 上篇主要介绍了使用线程池的好处以及ExecutorService接口,然后学习了通过Executors工厂类生成满足不同需求的简单线程池,但是有时候我们需要相对复杂的线程池的时候就需要我们自己 ...

  3. 自定义线程池的名称(ThreadPoolExecutor)

    目的:有时候为了快速定位出现错误的位置,在采用线程池时我们需要自定义线程池的名称. 1.创建ThreadFactory(ThreadPoolExecutor默认采用的是DefaultThreadFac ...

  4. 自定义线程池ThreadPoolExecutor

    使用自定义的方式创建线程池 Java本身提供的获取线程池的方式 使用Executors直接获取线程池,注意,前四个方式的底层都是通过new ThreadPoolExecutor()的方式创建的线程池, ...

  5. java多线程(四)-自定义线程池

    当我们使用 线程池的时候,可以使用 newCachedThreadPool()或者 newFixedThreadPool(int)等方法,其实我们深入到这些方法里面,就可以看到它们的是实现方式是这样的 ...

  6. Java自定义线程池-记录每个线程执行耗时

    ThreadPoolExecutor是可扩展的,其提供了几个可在子类化中改写的方法,如下: protected void beforeExecute(Thread t, Runnable r) { } ...

  7. SpringBoot 自定义线程池

    本教程目录: 自定义线程池 配置spring默认的线程池 1. 自定义线程池 1.1 修改application.properties task.pool.corePoolSize=20 task.p ...

  8. Executors提供的四种线程池和自定义线程池

    JAVA并发编程——EXECUTORS 线程池的思想是一种对象池的思想,开放一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理.当有线程任务时,从池中取一个,执行完毕,对象 ...

  9. Android AsyncTask 深度理解、简单封装、任务队列分析、自定义线程池

    前言:由于最近在做SDK的功能,需要设计线程池.看了很多资料不知道从何开始着手,突然发现了AsyncTask有对线程池的封装,so,就拿它开刀,本文将从AsyncTask的基本用法,到简单的封装,再到 ...

随机推荐

  1. Python之Fabric

    [Fabric] Fabric是一个用Python开发的部署工具,最大特点是不用登录远程服务器,在本地运行远程命令,几行Python脚本就可以轻松部署. 安装 wget https://bootstr ...

  2. Gridview 尾部添加总计

    1.GridView控件showfooter的属性=true 2. int totalZJ, iZJ; protected void GridView1_RowDataBound(object sen ...

  3. APUE学习笔记——8.1-8.4 进程基础

    进程ID 1 进程id是唯一的.(不会有进程id一样的两个进程) 2进程id是可复用的,一个进程销毁后,它的id号可以被新的进程使用.但是Unix采用了延迟复用的算法,也就是进程   销毁后它的id不 ...

  4. 【导航】JennyHui没有宏大的计划,只有坚持!坚持!

    学英语 口语  Bingo口语笔记 听力 VOA 词汇 生词积累 座右铭 随手记 TED X - > 笔记 JennyHui要成为程序猿(加油!!菜鸟终会成为大牛的!!) 后端知识 Python ...

  5. threejs 世界坐标与屏幕坐标相互转换

    屏幕坐标转世界坐标: let pX = (screenPoint.x / this.scene.renderer.domElement.clientWidth) * 2 - 1; let pY = - ...

  6. spring加载jar包中多个配置文件(转载)

    本文转载自:http://www.cnblogs.com/GarfieldTom/p/3723915.html

  7. Codeforces1070 2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred)总结

    第一次打ACM比赛,和yyf两个人一起搞事情 感觉被两个学长队暴打的好惨啊 然后我一直做傻子题,yyf一直在切神仙题 然后放一波题解(部分) A. Find a Number LINK 题目大意 给你 ...

  8. Win32 程序在启动时激活前一个启动程序的窗口

    UWP 程序天生单实例.当然,新 API (10.0.17134)开始也提供了多实例功能.不过,传统 Win32 程序可就要自己来控制单实例了. 本文介绍简单的几个 Win32 方法调用,使 Win3 ...

  9. 神器如 dnSpy,无需源码也能修改 .NET 程序

    dnSpy 是 0xd4d 开发的 .NET 程序调试神器. 说它是神器真的毫不为过!它能在完全没有源码的情况下即时调试程序,甚至还能修改程序!本文讲向大家介绍如何使用 dnSpy 修改 .NET 程 ...

  10. PAT 1009 说反话 C语言

    给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出. 输入格式:测试输入包含一个测试用例,在一行内给出总长度不超过80的字符串.字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区 ...