多线程基础(五)---线程池

线程池介绍

线程池是一种采用池化思想的管理线程的工具。
作用:
【1】减少资源消耗,减少线程创建和销毁的时间开销,快速响应,复用已有线程

【2】减低复杂度,将任务的提交和执行解耦,我们只需要创建一个线程池,然后提交任务就可以,具体的执行交由线程池管理

【3】提高线程的可管理性,安全有效管理资源,避免无限制申请照成的资源耗尽

【3】提高响应速度,任务到达时候直接复用已有线程。

JUC下的ThreadPoolExecutor,采用池化思想来管理一定数量的线程来调度执行提交的任务。

1、线程池的使用场景

快速响应的场景,如注册场景,用户注册完成后,进行邮件和手机短信通知,通知服务可以放在线程池中进行异步完成,直接返回客户端成功注册,提升用户体验

2、ThreadPoolExecutor有哪些参数?(加上线程的执行流程)

核心线程数,最大线程数,空闲线程超时时间、时间单位、阻塞队列、拒绝策略、线程工厂
【1】判断线程池的状态,如果不是RUNNING状态,执行拒绝策略
【2】线程数 < 核心线程数,创建新线程执行任务
【3】线程数 > 核心线程数且任务队列没满,放入任务队列等待执行
【4】核心线程数<线程数<最大线程数,任务队列满了,创建新线程执行提交的任务
【5】线程数>最大线程数,且队列已满,执行拒绝策略

3、平时是如何使用线程池的?Executors了解吗?

阿里巴巴Java开发规范明确说明不能使用Executors来创建线程池,使用ThreadPoolExecutor来进行创建
知道 Executors 工具类,很久之前有用过,也踩过坑,Executors 创建的线程池有发生 OOM 的风险。
Executors.newFixedThreadPool 和 Executors.SingleThreadPool 创建的线程池内部使用的是无界(Integer.MAX_VALUE)的 LinkedBlockingQueue 队列,可能会堆积大量请求,导致 OOM。
Executors.newCachedThreadPool 和 Executors.scheduledThreadPool 创建的线程池最大线程数是用的Integer.MAX_VALUE,可能会创建大量线程,导致 OOM。
实际在Spring中使用线程池比较多,但不使用JUC提供的线程池,而是使用ThreadPoolTaskExecutor或者DynamicTp框架下的线程池,使用JUC线程池在IOC容器关闭的时候,可能任务队列还没有处理完导致任务丢失的问题。
一般都交由Spring进行管理,动态调整线程池的一个参数

4、设置核心线程数为多少?

实际一个服务中有很多线程,tomcat,GC、各种框架、中间件,这些都会占用线程资源。需要通过压测不断的动态调整线程池参数,观察 CPU 利用率、系统负载、GC、内存、RT、吞吐量等各种综合指标数据,来找到一个相对比较合理的值。

5、线程池的拒绝策略有哪些?

当阻塞队列已满并且已经到达最大线程数,再次提交任务会走拒绝策略,JDK内置4中拒绝策略
1)AbortPolicy:线程池默认的拒绝策略,触发时会抛出 RejectedExecutionException 异常。如果是一些比较重要的业务,可以使用该拒绝策略,在系统不能进一步支持更大并发量的情况下通过抛出异常及时发现问题并进行处理。
2)CallerRunsPolicy:在线程池没关闭的情况下,由调用者线程去处理任务,反之直接丢弃。此拒绝策略追求任务都能被执行,不丢失,比较适合并发量不大并且不允许丢失任务的场景场景,性能较低。
3)DiscardPolicy:丢弃任务,不抛出异常,一般无感知。建议一些无关紧要的任务可以使用此策略。
4)DiscardOldestPolicy:丢弃队列中最老的任务,然后重新提交被拒绝的任务。需要根据业务场景进行选择是否要用

参考:
https://blog.csdn.net/m0_37840000/article/details/79756932

posted @ 2024-10-09 11:28  goodguyly  阅读(3)  评论(0)    收藏  举报