当我要去了解Java线程池设计思想时候,网上的讲解都是没有讲解到核心问题,大多数都是贴代码讲解,没办法我只能去调试jdk中源码来了解,本文是给我有一样疑问的人讲解线程池设计思想,而不是针对具体实现。
线程池的演进
- 现在需要创建大量的任务,给出一个场景思考,假设需要处理10000个任务,如下图所示,我们来分析一下以下传统方式的弊端
- 问题1)假设当前电脑为4核处理器,理想状态是创建4个或8个任务比较好(
这里的数量只是简单说明,不用深究
),那么,当线程数量超过8个以后将会下降,因为CPU会频繁切换,为了保持当前线程的上下文(可以理解为当前线程的状态,包括执行代码的位置和数据的保存
),所以线程的数量对线程的影响还是比较大的。
- 问题2)线程(英语:thread)是操作系统能够进行运算调度的最小单位。也就是说,要执行一次任务,需要为这个任务准备基本的资源,比如说内存、IO等。那么完成一次任务的过程,实际有效的也就是任务执行的时间,如下图所示
也就是,当前线程执行的效率为=执行线程/(创建线程+执行线程+销毁线程)
,当我们需要创建10000个线程,那么将会有很多的开销 - 问题3)创建大量线程内存空间的开销,当前我们创建的10000个线程,或许还可以创建出来,假设现在需要创建1000000000个线程呢?那么JVM会不会挂掉?如何优化?
针对以上问题,引入JDK中ThreadPoolExecutor 的线程池设计思想
ThreadPoolExecutor设计思想
线程池设计核心思想包括两部分,如下图所示
工作线程Worker
,实现线程Thread执行类,执行任务从定义任务或者任务队列中获取任务队列
,当工作线程Worker数据为3时候,当前定义任务为10个,那么当工作线程Worker还未执行完毕,多余的7个任务将存储在任务队列上
回顾线程池如何传统线程问题
- 线程数量
- 线程的创建和销毁
- 大量线程创建与jvm关系
由于引入工作线程Worker
,线程中的数量明确控制,解决问题1。工作线程Worker
是从任务队列或定义任务中拿取任务执行,所有不会频繁的创建线程和销毁,解决问题2.引入任务队列,当任务队列存储大小固定,这里举例为100,那么当任务超过100后,将采集策略,如拒绝任务的执行,直接丢弃、或者抛出异常等方法,解决问题3
总结
以上为线程池大概思路,不涉及具体细节实现,对于了解线程池设计可以了,基于以上思想,可以自实行线程池,接下来,将简单分析一下jdk源码,将线程池思想落地链接:Java线程池核心代码分析 jdk1.8 (ThreadPoolExecutor 二)