线程池相关

线程池:线程池和数据库连接池非常类似,可以统一管理和维护线程,减少没有必要的开销。

1.为什么需要使用线程池
因为频繁开启线程和停止线程,线程需要从新被cpu从就绪到运行状态调度,需要发生cpu上下文切换,效率非常低。

线程池是复用机制

提前创建好一些固定的线程数一致在运行状态实现复用,从而可以减少就绪到运行状态的切换。

2.哪些地方会用到线程池

实际开发中禁止使用new线程

必须使用线程池来维护和创建线程池

常用 发送邮件 发送短信的时候

3.线程池有哪些好处

核心点:复用机制 提前创建好固定的线程一直在运行状态 实现复用 限制线程创建数量

1」降低资源消耗

2」提高响应速度

3」提高线程的可管理性

4」提供更多更强大的功能;比如说 延时定时线程池

4.线程池的创建方式

Executors.newCachedThreadPool() 可缓存线程池

Executors.newFixedThreadPool() 可定长度

Executors.newScheduledThreadPool() 可定时

Executors.newSingleThreadExecutor() 单例

底层都是基于ThreadPoolExecutor 构造函数封装 

5.线程池底层如何实现复用

  •  提前创建好固定的线程一直在运行状态 -----死循环实现
  • 提交的线程任务缓存到一个并发队列集合中,交给正在运行的线程执行
  • 正在运行的线程就从队列中获取该任务执行

6.ThreadPoolExecutor核心参数

  • corePoolSize:核心线程数
  • maximumPoolSize:最大线程数
  • keepAliveTime:超出corePoolSize后创建的线程存活时间
  • unit: keepAliveTime的时间单位
  • workQueue: 任务队列 用于保存待执行的任务
  • threadFactory: 线程池内部创建线程多用的工厂
  • handler: 任务无法执行时的处理器

7.线程池创建的线程会一直在运行状态吗?

不会。 我们可以配置超出核心线程数后创建的线程的存活时间例如为60s

在60s内没有核心线程一直没有任务执行,则会停止该线程。

8.线程池底层ThreadPoolExecutor原理实现

专业术语

  1. 当线程数小于核心线程数时,创建线程;
  2. 当线程数大于等于核心线程数,且任务队列未满时,将任务放入任务队列;
  3. 当线程数大于等于核心线程数,且任务队列已满时
  • 若线程数小于最大线程数,创建线程
  • 若线程数等于最大线程数,抛出异常,拒绝任务。

9.线程队列满了任务会丢失吗

 如果队列满了,且任务总数>最大线程数则当前线程走拒绝策略。

可以自定义拒绝异常,将该任务缓存到redis,本地文件,mysql中后期项目启动实现补偿

10.线程池拒绝策略有哪些

 new ThreadPoolExecutor.AbortPolicy()  队列满了  不处理  抛出异常

new ThreadPoolExecutor.CallerRunsPolicy()  返回到主线程  去帮忙执行

new ThreadPoolExecutor.DiscardPolicy() 队列满了  丢掉任务  不抛出异常

new ThreadPoolExecutor.DiscardOldestPolicy() 队列满了  任务和最早的线程中争抢资源   不抛出异常

11.为什么阿里巴巴不建议使用Executors

因为默认的Executors线程池底层是基于ThreadPoolExecutor构造函数封装的,采用误解队列存放缓存任务,会无限缓存任务容易发生内存溢出,会导致我们最大线程会失效。

### 线程池相关面试题解析 线程池是一种用于管理和复用线程的技术,旨在提高程序性能和资源利用率。以下是与线程池相关的常见面试题及其解答。 #### 1. 什么是线程池?为什么要使用线程池线程池是一组预先创建的可重用线程集合,这些线程由线程池统一管理,包括线程的创建、销毁以及任务调度等[^2]。 使用线程池的原因在于:频繁地创建和销毁线程会带来较大的系统开销,尤其是在高并发场景下可能导致性能下降或资源耗尽。通过复用已有的线程,线程池可以有效降低这种开销,并提升系统的响应速度和稳定性[^2]。 #### 2. 线程池的核心组件有哪些? 线程池的主要组成部分包括: - **核心线程数(corePoolSize)**:线程池中始终保持活跃的最小线程数量。 - **最大线程数(maximumPoolSize)**:线程池允许的最大线程数量。 - **任务队列(workQueue)**:用于存储等待执行的任务。 - **保持存活时间(keepAliveTime)**:当线程数超过核心线程数时,多余线程的空闲生存时间。 - **拒绝策略(RejectedExecutionHandler)**:当线程池无法继续接收新任务时所采用的处理方式[^1]。 #### 3. 什么是任务队列?它的作用是什么? 任务队列是线程池中用于暂存待执行任务的数据结构。在线程池中的线程忙碌时,新提交的任务会被放入任务队列中排队等待执行。任务队列的作用主要包括: - 缓冲任务请求,平滑突发流量。 - 控制任务提交速率与线程池处理能力之间的关系。 常见的任务队列类型有无界队列(如 `LinkedBlockingQueue`)、有界队列(如 `ArrayBlockingQueue`)和同步移交队列(如 `SynchronousQueue`)[^1]。 #### 4. 线程池有哪些常见的拒绝策略? Java 中提供了多种内置的拒绝策略,具体如下: - **AbortPolicy**:直接抛出异常,阻止系统正常运行。 - **CallerRunsPolicy**:由调用方线程执行该任务,从而降低提交任务的速度。 - **DiscardOldestPolicy**:丢弃最早进入队列的任务,尝试重新提交当前任务。 - **DiscardPolicy**:静默丢弃无法处理的任务,不作任何处理。 #### 5. Java 中常用的线程池实现有哪些? Java 提供了以下几种常用线程池实现: - **FixedThreadPool**:固定大小的线程池,适用于负载较稳定的场景。 - **CachedThreadPool**:可根据需要创建新线程的缓存线程池,适合执行大量短生命周期的任务。 - **SingleThreadExecutor**:仅有一个工作线程的线程池,确保所有任务按顺序串行执行。 - **ScheduledThreadPool**:支持定时和周期性任务调度的线程池[^1]。 #### 6. 如何合理配置线程池参数? 合理的线程池参数配置需考虑以下几个方面: - **CPU 密集型任务**:线程数通常设置为 CPU 核心数 + 1,以充分利用硬件资源。 - **IO 密集型任务**:由于 IO 操作会导致线程阻塞,建议增加线程数以弥补阻塞带来的效率损失。 - **任务队列容量**:根据业务需求设定合适大小,过大可能导致内存占用过高,过小则容易触发拒绝策略。 --- ### 示例代码:自定义线程池 以下是一个简单示例,演示如何通过 `Executors` 创建不同类型的线程池: ```java import java.util.concurrent.*; public class ThreadPoolDemo { public static void main(String[] args) throws InterruptedException { ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3); ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2); // 提交任务到 FixedThreadPool for (int i = 0; i < 5; i++) { int taskId = i; fixedThreadPool.submit(() -> { System.out.println("Task " + taskId + " is running on thread " + Thread.currentThread().getName()); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } }); } fixedThreadPool.shutdown(); // 关闭线程池 } } ``` 此代码展示了三种不同类型线程池的创建方法及任务提交流程。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值