Java面试必问之线程池的创建使用、线程池的核心参数、线程池的底层工作原理

一、前言

大家在面试过程中,必不可少的问题是线程池,小编也是在面试中被问啥傻了,JUC就了解的不多。加上做系统时,很少遇到,自己也是一知半解。如果还不了解线程池的小伙伴,一定要认真看完,你会有收获的哈!!最后也为大家汇总了一套2022Java面试题,需要的小伙伴私信【面试】哦

二、线程池创建使用

答:使用Executors看一下源码是有好多个,经常用的也就三个,今天就展示靠上的五种。

//创建一个定长线程池,超出的线程会在队列中等待ExecutorService executorService = Executors.newFixedThreadPool(5);//创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,ExecutorService executorService1 = Executors.newSingleThreadExecutor();//创建一个可缓存线程池,可以自动扩容,扩容大小为int最大值,因为太大可以直接理解为无限大ExecutorService executorService2 = Executors.newCachedThreadPool();//创建一个定长线程池,该线程池可以安排命令在给定延迟后运行,或定期执行。ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);//1.8新增-创建一个带并行级别的线程池,并行级别决定了同一时刻最多有多少个线程在执行,不传参数默认为CPU个数// Runtime.getRuntime().availableProcessors()查看本机CPU个数ExecutorService executorService3 = Executors.newWorkStealingPool();

三、线程池的核心参数

//创建线程池,底层代码public ThreadPoolExecutor(int corePoolSize,                          int maximumPoolSize,                          long keepAliveTime,                          TimeUnit unit,                          BlockingQueue workQueue,                          ThreadFactory threadFactory,                          RejectedExecutionHandler handler) {    if (corePoolSize < 0 ||        maximumPoolSize <= 0 ||        maximumPoolSize < corePoolSize ||        keepAliveTime < 0)        throw new IllegalArgumentException();    if (workQueue == null || threadFactory == null || handler == null)        throw new NullPointerException();    this.corePoolSize = corePoolSize;    this.maximumPoolSize = maximumPoolSize;    this.workQueue = workQueue;    this.keepAliveTime = unit.toNanos(keepAliveTime);    this.threadFactory = threadFactory;    this.handler = handler;}

1. corePoolSize:线程池中的核心线程数,核心线程会一直存在,即使没有任务执行。

2. maximumPoolSize:线程池能够容纳同时执行的最大线程数,此值必须大于等于1

3. keepAliveTime:当线程数大于核心数时,这是多余空闲线程在终止前等待新任务的最长时间。(意思就是本来核心线程三个,已占满,扩展到最大线程数到5,解决完后没有线程任务了,这时设置一个时间,过了这个时间被扩展的2个非核心线程会被回收)

4. unit:keepAliveTime的时间单位。

5. workQueue:任务队列,被提交但尚未被执行的任务,相当于去饭店吃饭,餐桌满了,要在外边排队(阻塞队列)

6. threadFactory:表示生成线程池中工作线程的线程工厂,用于创建线程一般用默认的即可。

7. handler:拒绝策略,表示当队列满了并且工作线程大于等于线程池的最大线程数。

四、线程池的底层工作原理

- 主要处理流程图(来源百度)

Java面试必问之线程池的创建使用、线程池的核心参数、线程池的底层工作原理_第1张图片

- 底层工作原理图

Java面试必问之线程池的创建使用、线程池的核心参数、线程池的底层工作原理_第2张图片

打开UC浏览器 查看更多精彩图片

- 流程梳理

1. 在创建了线程池后,等待提交过来的任务请求。

 2. 当调用execute()方法添加一个请求任务时,线程池会做如下判断: 2.1 如果正在运行的线程数量小于corePoolSize,那么马上创建线程运行这个任务; 2.2 如果正在运行的线程数量大于或等于corePoolSize,那么将这个任务放入队列; 2.3 如果这时候队列满了且正在运行的线程数量还小于maximumPoolSize,那么还是要创建非核心线程立刻运行这个任务; 2.4 如果队列满了且正在运行的线程数量大于或等于maximumPoolSize,那么线程池会启动饱和拒绝策略来执行。

 3.当一个线程完成任务时,它会从队列中取下一个任务来执行。

 4.当一个线程无事可做超过一定的时间(keepAliveTime)时,线程池会判断: 如果当前运行的线程数大于corePoolSize,那么这个线程就被停掉;所以线程池的所有任务完成后它最终会收缩到corePoolSize 的大小。

五、总结

这样就理解很透彻了,我也为大家汇总了一套2022Java面试题,需要的小伙伴私信【面试】呀

你可能感兴趣的:(Java面试,java,面试,开发语言,架构,后端)