自定义:线程池和它里面的线程

顾名思义,线程池,里面就是放线程的,使用线程池的目的是为了线程的复用,前面说过,(如果)大量线程的不停创建和销毁是很浪费时间的,而且线程被创建后,本身也会占用内存,所以,如果大量地使用线程,会降低系统的性能。线程池中的线程没什么不同,都是通过ThreadFactory接口创建出来。

来看看这个“线程工厂”ThreadFactory的源码:

public interface ThreadFactory {

Thread newThread(Runnable r);

}

接口里只有一个newThread的方法,就是创建一个新的线程,新建线程池后,线程池都会通过这个方法来创建线程,因为在ThreadPoolExecutor类中它就有ThreadFactory这个参数:

对于这个ThreadFactory接口,我们可以重写它里面的newThread()方法来实现对线程池里线程的自定义,简单地来看个例子:

代码第12-20行,我们让线程做的事情很简单,就输出自己的Name和Id就行了。关键看main函数里,在新建线程池时我们使用ThreadPoolExecutor类,上一篇日志也说过了,三种线程池newFixedThreadPool()、newSingleThreadPool()和newCachedThreadPool()方法内部都是调用了ThreadPoolExecutor实现,只是传入参数不同来实现不同功能的线程池,所以我们可以用ThreadPoolExecutor新建线程池,并重写里面的ThreadFactory接口的newThread方法来实现自定义线程池里的线程。

    我们设置线程池里线程数为5个,最大线程数也为5个,使用的是无界队列,即当线程池中没有空闲线程时,被提交的任务会放到一个任务等待队列中,且不会存在任务进入等待队列失败的情况,直到系统的内存用完才会产生拒绝服务。当线程池中出现空闲线程后,会从任务等待队列中抽出一个任务来执行。第6个参数就是threadFactory,我们要重写的接口。代码第32行开始重写ThreadFactory接口里的newThread方法,我们可以让线程池里的线程创建时做一些其他事情,例如设置它的Id,这里我只让它在创建线程时输出自己的Id,当然你也可以让它做更多的事情。

 

以上是对线程池里的线程做自定义修改,通过重写ThreadPoolExecutor里的ThreadFactory接口。对于ThreadPoolExecutor,它也有些接口可以重写,来让线程池做更多的事情,这三个接口分别是线程池运行前、运行结束后、和运行结束的操作,来看看源码:

在实例化线程池ThreadPoolExecutor时,我们就可以直接对这三个接口做重写:

代码第31到48行,在三个接口,线程池执行任务前,任务执行完成后和线程池运行结束后都做了重写,让它们输出一下语句。

      翻了一些文档说:“在默认的ThreadExecutor实现中,提供了空的beforeExecute()和afterExecute()实现。在实际应用中,可以对其进行扩展来实现对线程池运行状态的跟踪,输出一些有用的调试信息,以帮助系统故障诊断。”回看上面的代码,重写这些接口让它们输出信息后,可以在线程池里任务执行前、执行后和线程池退出时都打印出来,对程序的调试是有帮助的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值