JUC高并发编程相关的面试题
1.谈谈什么是JUC
JUC 是 java.util.concurrent工具包简称,是一个处理线程的工具包。JDK1.5开始出现
2.为什么要使用线程池
因为频繁的开启线程或者停止线程,线程需要从新被cpu从就绪到运行状态的调度,需要发生cpu的上下文的切换,效率非常的低。
3.你们哪儿些地方会用到线程池
实际的开发中禁止自己new线程所以必须使用线程池来维护和创建线程注意下:不会使用到jdk自带的Executor线程池,都是根据ThreadPoolExecutor构造函数来实现封装
4.线程池有哪些作用
线程池
数据库连接池
本质原理:复用机制
创建了一个线程不会被立即销毁。而是一直被复用。
提前创建好五个线程一直运行状态。避免cpu从就绪到运行状态的调度,从而提高效率。
核心点:复用机制提前创建好固定的线程一直在运行状态 实现复用 限制线程创建的数量。
1.降低资源的消耗:通过线程池技术重复利用已创建的线程,降低线程的创建和销毁造成的损耗。
2.提高响应速度: 任务到达时,无需等待线程创建即可立即执行·
3.提高线程的可管理性:线程是稀缺资源,如果无限制创建,不仅会消耗系统资源,还会因为线程的不合理分布导致资源调度失衡,降低系统的稳定性。使用线程池可以进行统一的分配、调优和监控。
4.提供更强大的功能:线程池具备可拓展性,允许开发人员向其中增加更多的功能。比如延时定时线程池ScheduledThreadPoolExector,就允许任务延期执行或者是定期执行。
5.线程池的创建方式
Executor.newCachedThreadPool();可缓存的线程池
Executor.newFixedThreadPool();可定长度的线程池
Executor.newScheduledThreadPool();可定时的线程池
Executor.newSingleThreadPool();单例线程池
底层都是基于ThreadPoolExecutor构造函数封装的
6.线程池的底层是如何实现复用的
本质思想:创建一个线程,不会立马停止或者销毁而是一直实现复用。
提前创建好固定大小的线程一直保持在正在运行的状态;(可能会非常的消耗cpu的资源)
当需要线程执行任务,将该任务缓存在并发队列中;如果缓存队列满了,则会执行拒绝策略;
正在运行的线程从并发队列中获取任务执行从而实现多线程的复用问题
线程池的核心点:复用机制
提前创建好固定的线程一直在运行的状态-----死循环实现
提交的线程任务缓存到一个并发队列集合中,交给正在运行的线程运行
正在运行的线程就从队列中获取该任务执行
简单模拟手写Java线程池:
7.ThreadPoolExecutor核心的参数有哪些
corePoolSize:核心线程数量 一直正在保持运行的线程
maximumPoolSize:最大线程数,线程池允许创建的最大线程数。
keepAliveTime:超过corePoolSize后创建线程的存活时间
unit:keepAliveTime的时间单位
workQueue:任务队列,用于保存待执行的任务
threadFactory:线程池内部创建线程所用的工厂
handler:任务无法执行时的处理器。
8.线程池创建的线程会一直在运行的状态吗?
不会
例如:配置核心线程数corePoolSize为2,最大线程数为maximumPoolSize为5,我们可以配置超出corePoolSize核心线程数后创建的线程存活时间为60s 在60s内没有核心线程一直没有任务执行,则会停止该线程。
9.为什么阿里巴巴不建议使用Exectors
因为Exectors线程池底层是基于ThreadPoolExecutor构造函数封装的,采用的无界队列存放缓存任务,会无限缓存任务发生内存溢出。会导致我们最大线程数会失效。
在这里插入图片描述