1 缘起
怎么想起来看线程池的代码?
很简单,因为我不会用。
原先遇到用线程池一直是 Executors
直接构造一个出来。啊,newFixedThreadPool
就是创建定容线程池,线程数是固定的;newSingleThreadExecutor
就是创建一个单线程的任务队列,一个一个执行,好简单啊,线程池不过如此。
然而有一天我读了《阿里巴巴 Java 开发手册》,手册第一章第六条第四点明确指出:
【强制】线程池不允许使用
Executors
去创建,而是通过ThreadPoolExecutor
的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
说明:Executors
返回的线程池对象的弊端如下:
1)FixedThreadPool
和SingleThreadPool
:允许的请求队列长度为Integer.MAX_VALUE
,可能会堆积大量的请求,从而导致 OOM。
2)CachedThreadPool
和ScheduledThreadPool
:允许的创建线程数量为Integer.MAX_VALUE
,可能会创建大量的线程,从而导致 OOM。
而当我想尝试手动实例化 ThreadPoolExecutor
时:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
复制代码
复杂的构造器令我望而却步,当我“X度”Java 线程池
时,呈现给我的大多都是 Executors
的用法以及关于线程池的基本介绍,能把 ThreadPoolExecutor
讲清楚的没有几个(也或许是小豹子笨,看不太懂),因此我觉得,去看官方文档,去看代码才能最直观的去理解其中的原理!
小豹子想说:各位初学的小萌新,一定养成看官方文档的习惯(最好直接看英文的,官方文档即便是中文,翻译往往也滞后,我就被旧版本的
Spring
中文官方文档坑过)。官方文档是最了解该程序的人写的最正确的文档,这里边有什么坑,有什么骚操作,官方文档都会一一告诉你。
而“X度”的各种博客,我们很难保证其正确性,不要迷信它们,要“批判性”的欣赏,毕竟写博客是没有门槛的(就连我一个豹子都能写 ʅ(´◔౪◔)ʃ )。写的好的博客往往是记录解决一个问题的历程,或者对于某功能实现自己的创新等等,我们可以从中窥见博主的思想与思路。而罗列知识点类的、粗而广介绍类的、没有博主自己的思想蕴含在其中的博客,恕小豹子直言,不如去看官方文档。
2 计划
ThreadPoolExecutor
是一个两千行的大类,没关系我们一点一点去啃它。但内容实在太多,所以我觉得用系列文章的形式来记录我学习代码的过程比较好:
- 介绍为什么,以及打算怎么做
- 阅读类初始化及构造器代码,弄清楚我们 new 了一个什么东西
- 当我们提交一个任务时,发生了什么
- 如何控制线程池的行为
- 如何扩展线程池以实现我们自定的特性
阅读代码时,小豹子的经验是:一定要观察动态的代码!要边调试边看代码,观察变量运行时的状态。希望你能陪着小豹子一起,一步一步调试,查看自己机器上代码的运行状态,主动思考,我们会成长更多。
系列文章
小豹子还是一个大三的学生,小豹子希望你能“批判性的”阅读本文,对本文内容中不正确、不妥当之处进行严厉的批评,小豹子感激不尽。