# 线程池参数
# 简要回答
- 线程池的构造函数有七个参数,分别是核心线程数(corePoolSize)、最大线程数(maximumPoolSize)、空闲线程存活时间(keepAliveTime)、时间单位(TimeUnit)、线程池任务队列(workQueue)、线程工厂(ThreadFactory)和拒绝策略(RejectedExecutionHandler)。
- 线程池的参数决定了线程池的并发能力,资源占用和任务处理策略,需要根据实际场景进行合理配置。
# 详细回答
- corePoolSize:核心线程数,线程池中长期存活的线程数
- 如果线程池中的线程数量小于核心线程数,这些线程处于空闲状态也不会被销毁
- maximumPoolSize:最大线程数,线程池最多能创建的线程数
- 当核心线程已满,任务队列已满时,如果当前线程小于最大线程数,就会创建新的线程执行此任务,否则触发拒绝策略。
- keepAliveTime:空闲线程存活时间。
- 当线程数大于核心线程数时,如果每个线程的空闲时间超过了keepAliveTime,这个线程就会被销毁,销毁线程数=当前线程数-核心线程数
- TimeUnit:时间单位,keepAliveTime的时间单位。
- workQueue:线程池的任务队列,线程池存放任务的队列,没有空闲线程执行新任务时,存储所有待执行任务。
- ThreadFactory:创建线程的工厂,通过此方法设置线程的优先级、线程命名规则以及线程类型(用户线程/守护线程)。
- RejectedExecutionHandler:拒绝策略,当线程池的任务超出线程池队列可以存储的最大值之后,执行的策略。
# 使用场景
线程池参数设置需要结合任务特性和系统资源综合判断,在避免资源浪费的同时防止任务堆积或线程竞争过度。
- CPU密集型任务(计算、排序)
- 任务消耗CPU资源,线程执行时阻塞少
- corePoolSize = CPU核心数 + 1 :减少线程切换开销。
- IO密集型任务(数据库、文件IO)
- 任务大部分时间等待IO,CPU利用率低。
- corePoolSize = CPU核心数 * 2 :利用空闲CPU处理更多任务,提高并发。
# 知识图解
- 线程池工作原理

# 知识扩展
- 扩展:
- 线程池种类:
- ScheduledThreadPoolExecutor:定时执行任务,支持定时执行和周期执行。
- FixedThreadPool:固定大小线程池,线程数量固定,核心线程数和最大线程数相同,不会创建更多线程处理任务。
- CachedThreadPool:可缓存线程池,在于线程数是几乎可以无限增加(最大Integer.MAX_VALUE,2^31-1),线程闲置时会进行回收。
- SingleThreadExecutor:使用唯一的线程去执行任务,原理和FixedThreadPool一样,如果线程在执行任务时发生异常,会重新创建新线程执行后续任务,适合所有任务需要按顺序执行场景。
- SingleThreadScheduledExecutor:和ScheduledThreadPool线程池相似,属于其特例,内部只有一个线程。
- 面试官可能追问:
- Q1:可不可以设置核心线程数为0?
- 可以,当核心线程数为0时,有新任务时会将任务添加到任务队列,如果此时工作的线程数为0,则创建一个线程来执行任务。
- Q2:线程池中的shutdown(),shutdownNow()这两个方法有什么作用?
- shutdown()使用后会置状态为SHUTDOWN,正在执行的任务会继续,没有被执行则中断,不会再往线程池中添加新的任务,否则抛出RejectedExecutionException。
- shutdownNow()使用后会置状态为STOP,正在执行任务的线程会中断,没有被执行的任务则返回。
- shutdownNow()终止线程调用的是Thread.interrupt()方法,如果线程中没有sleep,wait,Condition或者定时锁等应用,interrupt()方法是无法中断当前线程的,仍需等待正在执行的任务都执行完成了才能退出。
- Q3:提交给线程池中的任务可以被撤回吗?
- 可以,当向线程池提交任务时,会得到一个Future对象,通过Future对象可以取消任务。
- 调用Future中的cancel(boolean mayInterruptIfRunning)方法,该方法会尝试取消执行的任务,参数mayInterruptIfRunning表示是否允许取消正在执行的任务。如果设置为true,则表示允许取消正在执行的任务,如果设置false,则表示不允许取消正在执行的任务。
- Q4:如果corePoolSize=5,maximumPoolSize=10,队列容量=20,同时提交30个任务,执行流程是什么?
- 前五个任务由核心线程直接执行
- 20个任务进入队列等待
- 剩余五个任务创建非核心线程执行
- 如果后面再提交任务,会执行拒绝策略
评论
验证登录状态...