面试题答案
一键面试1. 核心线程数(corePoolSize)
- 设置建议:应根据服务器的CPU核心数以及请求处理的特性来设置。通常可以设置为CPU核心数的1 - 2倍。例如,如果服务器是4核CPU,可以将
corePoolSize
设置为4 - 8。 - 原因:核心线程会一直存活,不会因为空闲而被销毁。设置合适的核心线程数能够充分利用CPU资源,避免频繁创建和销毁线程带来的开销。在高并发短时间HTTP请求场景下,较多的核心线程可以快速处理请求,减少请求排队等待的时间。
2. 最大线程数(maximumPoolSize)
- 设置建议:要考虑系统资源(如内存等)的承受能力。一般可以在核心线程数的基础上,根据预估的最大并发请求数进行适当放大。但不能设置过大,防止耗尽系统资源。比如可以设置为核心线程数的2 - 5倍。
- 原因:当核心线程数被占满且请求队列也已满时,线程池会创建新的线程直到达到最大线程数。合理设置最大线程数可以应对突发的高并发请求,同时避免因创建过多线程导致系统资源耗尽(如内存溢出等问题)。
3. 队列容量(workQueue)
- 设置建议:可以选择无界队列(如
LinkedBlockingQueue
)或有界队列(如ArrayBlockingQueue
)。如果选择有界队列,其容量设置需综合考虑系统能承受的请求堆积数量。例如,可设置为几百到几千,具体根据应用实际情况。 - 原因:无界队列会将所有任务都放入队列,直到内存耗尽,适合任务处理速度较快且对请求处理顺序有要求的场景。有界队列可以防止任务无限堆积导致内存问题,当队列满时,线程池会创建新线程(直到最大线程数)。合理设置队列容量能平衡线程创建开销和请求处理能力。
4. 线程存活时间(keepAliveTime)和时间单位(unit)
- 设置建议:对于短时间HTTP请求场景,
keepAliveTime
可以设置得相对较短,如5 - 10秒,单位可选择TimeUnit.SECONDS
。 - 原因:非核心线程在空闲时间达到
keepAliveTime
后会被销毁。设置较短的存活时间可以及时释放多余的线程资源,避免线程长时间闲置占用资源,提高资源利用率。
5. 拒绝策略(RejectedExecutionHandler)
- 设置建议:常见的拒绝策略有
AbortPolicy
(默认,直接抛出异常)、CallerRunsPolicy
(将任务回退给调用者执行)、DiscardPolicy
(直接丢弃任务)、DiscardOldestPolicy
(丢弃队列中最老的任务)。在高并发Web应用场景下,CallerRunsPolicy
可能较为合适。 - 原因:
CallerRunsPolicy
能让调用者线程来执行任务,这样可以在一定程度上减轻线程池和队列的压力,同时保证任务不会被直接丢弃。虽然调用者线程执行任务会影响调用者自身的处理速度,但在高并发场景下能提供一种兜底策略,避免任务丢失。