一、前言
最近学习了线程池的一些知识,之前也是用过,不过通过这次的学习后收获颇丰,在此做个记录。
二、介绍
1、线程池基础:概念介绍
1.1什么是线程池
线程池其实就是一种多线程处理形式,处理过程中可以将任务添加到队列中,然后在创建线程后自动启动这些任务。这里的任务就是我们实现了Runnable或者Callable接口的实例对象。
1.2为什么使用线程池
使用线程池最大的原因就是可以根据系统的需求和硬件环境灵活的控制现成的数量,且可以对所有线程进行统一的管理和控制,从而提高系统的运行效率,降低系统运行压力;当然,使用线程池的原因不仅仅只有这些,我们可以从线程池自身的优点上来进一步了解线程池的好处。
1.3使用线程池的优势
(1)线程和任务分离,提升线程重用性
(2)控制线程并发数量,降低服务器压力,统一管理所有线程
(3)提升系统响应速度,假如创建线程用的时间为T1,执行任务用的时间为T2,销毁线程用的时间为T3,那么使用线程池就免去了T1和T3的时间
2、Java内置线程池介绍
2.1Java内置线程池原理剖析
我们要想自定义线程池,必须先了解线程池的工作原理,才能自己定义线程池。我们通过观察Java中的ThreadPoolExecutor的源码来学习线程池的原理。我们可以看到有4个构造方法:
ThreadPoolExecutor构造方法这里就选择最后一种来举例说明下。
public ThreadPoolExecutor(int corePoolSize, // 核心线程数量
int maximumPoolSize, // 最大线程数
long keepAliveTime, // 最大空闲时间
TimeUnit unit, // 时间单位
BlockingQueue<Runnable> workQueue, // 任务队列
ThreadFactory threadFactory, // 线程工厂
RejectedExecutionHandler handler // 饱和处理机制
) {
......
}
2.2参数解释见源码文字
(1)核心线程数(corePoolSize)
核心线程数的设计需要依据任务的处理时间和每秒产生的任务数量来确定,例如:执行一个任务需要0.1秒,系统80%的时间每秒都会产生100个任务,那么要想在1秒内处理完100个任务,就需要10个线程,测试可以设计核心线程数为10。当然实际情况不会这么平均,所以一般按照8020原则设计即可,即按照80%的情况设计核心线程数,剩下的20%可以利用最大线程数处理。
(2)任务队列长度(workQueue)
任务队列长度一般设计为:核心线程数/单个任务执行时间*2即可,例如上述场景中,核心线程数为10,单个任务执行时间为0.1秒,则队列长度可以设计为200.
(3)最大线程数(maximumPoolSize)
最大线程数的设计除了需要参照核心线程数的设计外,还需要参照系统每秒产生的最大任务数决定,例如上述环境中,如果系统每秒最大产生的任务是1000个,那么最大线程数=(最大任务数-任务队列长度)*单个任务执行时间,即:最大线程数=(1000-200)*0.1=80个。
(4)最大空闲时间(keepAliveTime)
这个参数的设计完全参考系统运行环境和硬件压力设定,没有固定的参考值,用户可以根据经验和系统产生任务的时间间隔合理设置一个值即可。
2.3线程池工作流程总结示意图
线程池工作流程总结示意图参考:网易云课堂-全面深入学习线程池
网友评论