线程池
简介
线程池是一种利用池化思想来实现的线程管理技术
类似的利用池化思想的技术还有MySQL的连接池,JVM的字符串常量池,Netty的基于池化技术的ByteBuf
可以看到这些被池化的资源都是十分珍贵的资源:网络连接,内存,线程
它们都有一个特点:
那就是可以被复用
程序可以通过一个连接发起多次请求
对于同样的数据,多个地方可以指向同一块内存
可以让线程不断执行用户提交的任务
将这些资源池化管理的好处
1、最大程度的利用这些资源
2、方便管理这些资源
3、复用资源,减少对重复资源的频繁创建和销毁
线程池
对于线程池而言,管理的是线程资源
我们都知道同一时间能并行执行多少线程取决于CPU核心数
同一CPU能并发执行多少线程取决于CPU的性能
如果用户使用线程没有规矩,随着频繁创建线程,导致线程频繁销毁,线程频繁切换,浪费了宝贵的线程资源
所以通过复用已经创建的线程,并对其进行统一管理,就可以最大化利用线程资源为我们提供服务
简单分析一下
继承体系
幸运的是,ThreadPoolExecutor
的继承体系并不复杂
顶级接口Executor
这个接口的作者是 Doug Lea
在Java并发领域,大哥李的名声可以说是如雷贯耳,线程池、AQS、原子类等等很多关于并发的工具都是出自这位大师的作品
可以看到,这个接口就一个类,定义了一个执行任务的规范
ExecutorService
ExecutorService
也是一个接口,继承了ExecutorService
,在此接口上做了很多拓展
比如定义shutdown
的规范,实现类需要遵循这些接口的定义
AbstractExectuorService
实现了ExecutorService
接口,实现了一些接口,方便子类调用
内部类
接下来看看ThreadPoolExecutor
有哪些内部类
CallerRunsPolicy
、AbortPolicy
、DiscardPolicy
、DiscardOldestPolicy
这四个内部类都是RejectedExecutionHandler
的实现类主要是提供了四个内置的拒绝策略
Worker
这个Worker类中封装了thread,是真正干活的类
它的父类AQS十分重要,后续会单独出文章讲
成员属性
什么核心线程数啊、线程工厂啊、拒绝策略啊都在成员变量里面
工作流程图
先给大家提供一张工作流程图