此答案节选自我们最近弄的
面试鸭刷题神器
,更多
大厂常问面试题
,可以点击下面的小程序进行阅读哈!
回答重点
答案是
默认不会被销毁
,但是可以通过配置
allowCoreThreadTimeO
ut 参数为 true 使得核心线程空闲后也会被回收!
顺着这题,我们再来过一遍如何回答
线程池原理
这道面试题。
首先,简述线程池的作用:线程池是一种池化技术,用于预先创建并管理一组线程,避免频繁创建和销毁线程的开销,提高性能和响应速度。
然后,简单带一下线程池的几个关键的配置:核心线程数、最大线程数、空闲存活时间、工作队列、拒绝策略。
最后,简述一下线程池的工作原理,按照下面的顺序来回答即可:
-
默认情况下线程不会预创建,任务提交之后才会创建线程(不过设置 prestartAllCoreThreads 可以预创建核心线程)。
-
当核心线程满了之后不会新建线程,而是把任务堆积到工作队列中。
-
如果工作队列放不下了,然后才会新增线程,直至达到最大线程数。
-
如果工作队列满了,然后也已经达到最大线程数了,这时候来任务会执行拒绝策略。
-
如果线程空闲时间超过空闲存活时间,并且线程线程数是大于核心线程数的则会销毁线程,直到线程数等于核心线程数(设置 allowCoreThreadTimeOut 为 true 可以回收核心线程,默认为 false)。
任务提交,线程池线程数还未达到核心线程数:
核心线程数已满,任务队列未满的情况:
核心线程数已满,任务队列已满的情况:
线程池中线程数已达最大线程数的情况:
注意,核心线程和非核心线程在线程池中是一样的,并没有特殊的标识区分!图中区分仅为说清创建的顺序
prestartAllCoreThreads 源码
线程池初始化会执行以下代码,默认的
prestartAllCoreThreads
为 false,因此默认不会创建核心线程。
不过,可以通过
setPrestartAllCoreThreads
将其改为 true。
processWorkerExit 源码
可以看到,根据
allowCoreThreadTimeOut
参数,实际可以控制线程池的最小线程数,使得核心线程数也可以被销毁。
扩展:线程池相关参数解释
-
corePoolSize:核心线程数,即线程池中始终保持的线程数量。
-
maximumPoolSize:最大线程数,即线程池中允许的最大线程数量。
-
keepAliveTime:线程空闲时间,超过这个时间的非核心线程会被销毁。
-
-
threadFactory:线程工厂,用于创建新线程。
-
rejectedExecutionHandler:任务拒绝处理器,当任务无法执行时的处理策略。
扩展:工作队列类型
-
SynchronousQueue:不存储任务,直接将任务提交给线程。
-
LinkedBlockingQueue:链表结构的阻塞队列,大小无限。
-
ArrayBlockingQueue:数组结构的有界阻塞队列。
-
PriorityBlockingQueue:带优先级的无界阻塞队列。
扩展:提供的线程池类型
Java 并发库中提供了哪些线程池实现?它们有什么区别?
扩展:线程池拒绝策略
Java 线程池有哪些拒绝策略?