面试题答案
一键面试核心参数含义及作用
- corePoolSize
- 含义:线程池中的核心线程数。
- 作用:即使这些线程处于空闲状态,也不会被销毁,除非设置了
allowCoreThreadTimeOut
为true
。线程池启动后,会优先创建核心线程来处理任务。当任务数量小于等于corePoolSize
时,新任务会直接分配给空闲的核心线程执行。
- maximumPoolSize
- 含义:线程池中允许的最大线程数。
- 作用:当任务队列已满,且已创建的线程数小于
maximumPoolSize
时,线程池会创建新的非核心线程来处理任务。但线程总数不会超过maximumPoolSize
,超过这个数量的任务将根据拒绝策略进行处理。
- keepAliveTime
- 含义:当线程池中的线程数量大于
corePoolSize
时,多余的空闲线程(非核心线程)能够保持存活的最长时间。 - 作用:如果一个非核心线程在
keepAliveTime
时间内没有接到新任务,就会被销毁,以释放资源。通过合理设置这个参数,可以避免过多的非核心线程长时间占用资源。
- 含义:当线程池中的线程数量大于
- unit
- 含义:
keepAliveTime
参数的时间单位。 - 作用:用于指定
keepAliveTime
是以秒、毫秒、分钟等哪种时间单位来衡量。例如TimeUnit.SECONDS
表示秒,TimeUnit.MILLISECONDS
表示毫秒等。
- 含义:
- workQueue
- 含义:任务队列,用于存放等待执行的任务。
- 作用:当核心线程都在忙碌时,新提交的任务会被放入这个队列中等待执行。常见的任务队列类型有
ArrayBlockingQueue
、LinkedBlockingQueue
、SynchronousQueue
等,不同的队列类型有不同的特性,会影响线程池的工作方式和性能。
- threadFactory
- 含义:线程工厂,用于创建新线程。
- 作用:可以通过自定义线程工厂来设置线程的一些属性,如线程名、线程优先级等,便于调试和管理线程。
- handler
- 含义:拒绝策略,当任务队列已满且线程数达到
maximumPoolSize
时,对新提交任务的处理策略。 - 作用:常见的拒绝策略有
AbortPolicy
(直接抛出异常)、CallerRunsPolicy
(将任务回退给调用者执行)、DiscardPolicy
(直接丢弃任务)、DiscardOldestPolicy
(丢弃队列中最老的任务,然后尝试提交新任务)。合理选择拒绝策略可以避免系统因无法处理过多任务而崩溃。
- 含义:拒绝策略,当任务队列已满且线程数达到
对内存管理的影响
- 线程内存占用:每个线程都会占用一定的内存空间,包括线程栈空间等。如果
maximumPoolSize
设置过大,可能会创建过多线程,导致内存占用过高,甚至引发OutOfMemoryError
。尤其是在创建大量线程的情况下,线程栈空间的累积消耗可能会非常可观。 - 任务队列内存占用:
workQueue
会占用内存来存储等待执行的任务。如果任务队列设置过大且任务长时间积压,可能会占用大量内存。例如使用LinkedBlockingQueue
且不设置容量上限时,可能会导致内存被耗尽。 - 资源释放延迟:如果
keepAliveTime
设置过长,多余的空闲线程长时间不被销毁,会持续占用内存资源。相反,如果设置过短,可能导致线程频繁创建和销毁,增加系统开销的同时也可能影响性能。 - 对象生命周期管理:线程池中的任务通常会涉及到一些对象的创建和使用。如果任务处理逻辑中对象没有及时释放,随着任务不断执行,可能会导致大量对象在内存中累积,影响内存回收,进而导致内存问题。