目录
1、线程池思想概述
2、什么是线程池?
3、不使用线程池的问题
4、线程池的工作原理
5、线程池实现的API、参数说明
5.1、谁代表线程池?
5.2、如何得到线程池对象
5.3、ThreadPoolExecutor构造器的参数说明
6、线程池常见面试题
6.1、临时线程什么时候创建啊?
6.2、什么时候会开始拒绝任务?
1、线程池思想概述
我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题:
如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为 频繁 创建线程 和 销毁线程 需要时候。
那么有没有一种方法使得线程可以复用,就是执行完一个任务,并不会被销毁,而是可以继续执行其他的任务有?
在Java中可以通过线程池来达到这样的效果。
2、什么是线程池?
- 线程池就是一个可以 复用线程的技术 。
3、不使用线程池的问题
- 如果用户每发起一个请求,后台就创建一个新线程来处理,下次新任务来了又要创建新线程,而创建新线程的开销是很大的,这样会严重影响系统的性能。
4、线程池的工作原理
- 核心线程:长久存活的线程
5、线程池实现的API、参数说明
5.1、谁代表线程池?
- JDK5.0起提供了代表线程池的接口:ExecutorService
5.2、如何得到线程池对象
- 方式一:使用ExcutorService的实现类ThreadPoolExecutor自创建一个线程池对象
- 方式二:使用Executors(线程池的工具类)调用方法返回不同特点的线程池对象
5.3、ThreadPoolExecutor构造器的参数说明
- 参数一:corePoolSize:指定线程池的线程数量(核心线程)长久不死亡的线程:不能小于0,线程池运行稳定时的数量,就是正式工的数量
- 参数二:maximumPoolSize:指定线程池可支持的最大线程数:最大数量 >= 核心线程数量,假设核心线程的数量是3,最大线程数量是10,意味着最多支持10个线程,有3个线程是不死的,7个线程用完之后可能会把它销毁掉 。最大线程数包含了核心线程数。
- 参数三:keepAliveTime:指定 临时线程 的最大存活时间:不能小于0,这个临时线程就是刚刚多出来的7个线程,相当于零时工 。
- 参数四:unit:指定存活时间的单位(秒、分、时、天)
- 参数五:workQueue:指定任务队列:不能为null,假设线程都满啦,假设最大10个线程都在忙,都在处理任务,那么新的任务来了,第11个任务过来的时候,它可以进到这个任务队列里,缓存起来,到时候还要处理 。任务阻塞队列,当核心线程不能及时处理任务时,任务会存在任务队列中。
- 参数六:threadFactory:指定用哪个线程工厂创建线程:不能为null,
- 参数七:handler:指定线程忙,任务满的时候,新任务来了怎么办:不能为null,比如现在最多10个线程,然后任务队列里面最多可以排5个任务,最多支持5个任务,10个线程已经都在忙,任务队列最多缓存5个任务,任务队列也已经满,10个线程处理10个任务,任务队列还有5个任务,所以第16个任务过来的时候怎么办?应该怎么拒绝第16个任务,配置拒绝策略,抛出异常或者不处理。当线程数达到最大线程数,任务阻塞队列已满,新的任务不能被接受处理时,拒接处理器 会拒绝本次任务。
- 生活例子解释7个参数:就像ktv,如果不用线程池,来一个客人招一个服务员,服务员是线程,突然来了500个客人,不可能招500个服务员,导致大量资源浪费,挣得钱还不够支付服务员的工资,正常ktv会招几个正式工,比如招3个正式工,3个正式工正常不会辞职,会一直服务,客人就是任务。
- corePoolSize:核心线程就是 3个 正式工
- maximunPoolSize:最大线程数 就是 3个正式工 + 7个零时工 = 10个最大线程数(员工)
- keepAliveTime:7个零时工 工作的 时间,过个这个时间就会被开除,但是3个正式工不会被开除
- unit:7个零时工工作时间的单位,工作多少秒、多少分、多少小时、多少天离职
- workQueue: ktv门口的那排5个座位,可以理解为ktv现在所有的房间都满了,没有空房间可以使用,这些客人需要等待,这些 等待的客人 就是任务
- threadFactory:可以理解为招人的人力资源部门,专门负责招人的,负责招 3个正式工 和 7个临时工
- hander:可以理解为现在ktv的所有房间都已经满了,10个员工都在服务这些客人,外面的5个等待座位也已经满了,此时来了第16波客人,我们应该采取什么措施去拒绝第16个任务
6、线程池常见面试题
6.1、临时线程什么时候创建啊?
- 新任务提交时发现核心线程都在忙,任务队列也满了,并且还可以创建临时线程,此时才会创建临时线程。
- 核心线程不足,都在使用,没有空闲的,任务队列也已经满了,处理新的任务时会创建扩展线程处理。
6.2、什么时候会开始拒绝任务?
- 核心线程和临时线程都在忙,任务队列也满了,新的任务过来的时候才会开始任务拒绝。