扩展ThreadPoolExecutor

ThreadPoolExecutor是可扩展的,它提供了几个可以在子类化中改写的方法:beforeExecute、afterExecute 和terminated,这些方法可以用于扩展ThreadPoolExecutor的行为。

在执行任务的线程中将调用beforeExecute和afterExecute等方法,在这些方法中还可以添加日志、计时、监视或统计信息收集的功能。无论任务是从run 中正常返回,还是抛出一个异常而返回,afterExecute都会被调用。(如果任务在完成后带有一个Error,那么就不会调用afterExecute。)如果beforeExecute 抛出一个RuntimeException,那么任务将不被执行,并且afterExecute也不会被调用。

在线程池完成关闭操作时调用terminated,也就是在所有任务都已经完成并且所有工作者线程也已经关闭后。terminated可以用来释放Executor 在其生命周期里分配的各种资源,此外还可以执行发送通知、记录日志或者收集finalize 统计信息等操作。

示例:给线程池添加统计信息

在程序清单8-9 的TimingThreadPool 中给出了一个自定义的线程池,它通过beforeExecute、afterExecute 和terminated 等方法来添加日志记录和统计信息收集。为了测量任务的运行时间,beforeExecute 必须记录开始时间并把它保存到一个afterExecute可以访问的地方。因为这些方法将在执行任务的线程中调用,因此beforeExecute可以把值保存到一个ThreadLocal变量中,然后由afterExecute来读取。在TimingThreadPool中使用了两个AtomicLong 变量,分别用于记录已处理的任务数和总的处理时间,并通过terminated来输出包含平均任务时间的日志消息。

                     程序清单8-9增加了日志和计时等功能的线程池                        

public class TimingThreadPool extends ThreadPoolExecutor {

private final ThreadLocal<Long>startTime

=new ThreadLocal<Long>();

private final Logger log =Logger. getLogger("TimingThreadPool");

private final AtomicLong numTasks =new AtomicLong();

private final AtomicLong totalTime =new AtomicLong();

protected void beforeExecute(Thread t, Runnable r){

super. beforeExecute(t,r);

log. fine(String. format("Thread %s:start %s",t,r));


protected void afterExecute(Runnable r, Throwable t){

try {

long endTime =System. nanoTime();

long taskTime =endTime -startTime. get();

numTasks. incrementAndGet();

totalTime'. addAndGet(taskTime);

log. fine(String. format("Thread %s:end %s, time=%dns",

t,r,taskTime) ) ;

}finally {

super. afterExecute(r,t);

}

}

protected void terminated(){

try {

log.info    (String. format("Terminated:avg time=%dns",

totalTime. get ( )  /  numTasks. get ( ) ) ) ;

}finally {

super. terminated();

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

栾还是恋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值