题外话
最近看了好多线程池课程,算是对于这个内容更熟悉了一点
正题
线程池
概念
是一种多线程处理形式,将任务添加至队列,然后在创建线程后自动启动这些任务
优点
我们为什么要用线程池呢,线程池的好处又是什么?
1.最大好处,重用存在的线程,减少每次启动,销毁线程的损耗
2.提高性能,可以有效控制最大并发线程数,提高系统资源利用率
3.方便管理,线程不能滥用,线程池可以有效控制线程数量,
缺点
1.会占用一定系统资源,线程池需要一些内存和系统资源维护线程池状态和管理线程
2.线程池过大可能会影响任务处理性能
线程池参数
线程池七大参数
1.核心线程数(corePoolSize):
指定线程池中的核心线程数量(最少的线程个数),线程池中会维护一个最小的线程数量,即
使这些线程处理空闲状态,他们也不会被销毁,除非设置了 allowCoreThreadTime0ut;
默认情况下,创建线程池之后,线程池中是没有线程的,需要提交任务之后才会创建线程
2.最大线程数(maximumPoolSize):指定线程池中允许的最大线程数,当核心线程全部繁忙且任务队列存满之后,线程池会临时追加线程,直到总线程数达到maximumPoolSize这个上限
最大线程数等于核心线程数 +非核心线程数
3.阻塞队列(BlockingQueue):
任务队列,当核心线程全部繁忙时,由execute/submit方法提交的Runnable任务存放到该
任务队列中,等待被核心线程来执行;
4.线程空闲超时时间(keepAliveTime):
线程空闲超时时间,如果一个线程处于空闲状态,并且当前的线程数量大于corePoolSize,
那么在指定时间后,这个空闲线程会被销毁;
5.线程空闲超时时间单位(TimeUnit):
keepAliveTime的时间单位(天、 小时、分、秒.....)
6.线程工厂(ThreadFactory):
线程工厂,用于创建线程,一般采用默认的即可,也可以自定义实现;
7.拒绝策略(RejectedExecutionHandler):
拒绝策略(饱和策略),当任务太多来不及处理时,如何拒绝任务;
任务拒绝是线程池的保护措施,当核心线程corePoolSize正在执行任务、线程池的任务队列
workQueue已满、并且线程池中的线程数达到maximumPoolSize时,就需要“拒绝”掉新提交过来的任务;
JDK提供了4种内置的拒绝策略: AbortPolicy 、CallerRunsPolicy 、DiscardOldestPolicy 和
DiscardPolicy;
1、AbortPolicy (默认) :丢弃任务并抛出RejectedExecutionException异常,这是线程池默认
的拒绝策略,在任务不能再提交的时候抛出异常,让开发人员及时知道程序运行状态,这样能:在系统不能承载更大的并发量时,及时通过异常信息发现;
2、DiscardPolicy: 直接丢弃任务,不抛出异常,使用此策略可能会使我们无法发现系统的异
常状态,建议一些无关紧要的业务采用此策略;
3、DiscardOldestPolicy:丢弃任务队列中靠最前的任务,并执行当前任务,是否要采用此拒绝
策略,根据实际业务是否允许丢弃老任务来评估和衡量;
4、CallerRunsPolicy: 交由任务的调用线程(提交任务的线程)来执行当前任务;这种拒绝策
略会让所有任务都能得到执行,适合大量计算类型的任务执行,使用这种策略的最终目标是要让每个任务都能执行完毕,而使用多线程执行计算任务只是作为增大吞吐量的手段;
线程池工作原理
请看以下图片
1.任务进来,核心线程数没有达到最大,创建核心线程执行任务
2.核心线程数满了,都在执行任务,剩余任务就进入阻塞队列等待
3.队列满了,线程数没有达到最大线程数,创建非核心线程
4.核心线程正在执行任务,达到了最大线程数,并且阻塞队列等待任务已满,就会采用拒绝策略
Executors类创建常见线程池
第一种: Executors . newFixedThreadPool()
功能:创建线程数固定大小的线程池
特点:核心线程数大小等于最大线程数大小,任务队列没有大小限制
注意事项:使用的时候队列无限大容易打爆内存
第二种:缓存线程池Executors.newCachedThreadPool()
功能:创建一个能立马把任务让线程来执行的线程池
特点:核心线程数为0,最大线程数没有限制,任务队列不存储任务,交给非核心线程直接执行
注意事项:这里比较适合执行时间较短的任务,能够提高并发量
第三种:单线程线程池Executors . newSingLe ThreadExecutor()
功能:创建一个只有1个工作线程的线程池
特点:核心线程和最大线程数都是1,任务队列无限大
注意事项:可以让任务有序的执行,但是任务队列无限大,容易打爆内存
第四种:周期执行任务的线程池Executors . newScheduLedThreadPool()
功能:创建一个可以周期来执行任务的线程池
特点:可以延期执行线程,也可以周期执行线程池
小结
此篇博客到此结束,有意见评论区见
求三连!!(点赞关注收藏)