GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • 卡码笔记-最强八股文
  • 计算机基础
  • Python
  • C++
  • Java
  • Go
  • ChatGPT充值
  • Claude充值
  • 国内使用Claude
  • 中转站推荐
  • 🔥大模型🔥
  • 大模型面经
  • Java面经
  • C++面经

This view

  • Original page
  • New address

GeezerVison is showing notes.kamacoder.com — 线程池参数|大厂面试题|Java高频面试题|核心线程数、最大线程数、任务队列、拒绝策略

# 线程池参数

# 简要回答

  • 线程池的构造函数有七个参数,分别是核心线程数(corePoolSize)、最大线程数(maximumPoolSize)、空闲线程存活时间(keepAliveTime)、时间单位(TimeUnit)、线程池任务队列(workQueue)、线程工厂(ThreadFactory)和拒绝策略(RejectedExecutionHandler)。
  • 线程池的参数决定了线程池的并发能力,资源占用和任务处理策略,需要根据实际场景进行合理配置。

# 详细回答

  1. corePoolSize:核心线程数,线程池中长期存活的线程数
    • 如果线程池中的线程数量小于核心线程数,这些线程处于空闲状态也不会被销毁
  2. maximumPoolSize:最大线程数,线程池最多能创建的线程数
    • 当核心线程已满,任务队列已满时,如果当前线程小于最大线程数,就会创建新的线程执行此任务,否则触发拒绝策略。
  3. keepAliveTime:空闲线程存活时间。
    • 当线程数大于核心线程数时,如果每个线程的空闲时间超过了keepAliveTime,这个线程就会被销毁,销毁线程数=当前线程数-核心线程数
  4. TimeUnit:时间单位,keepAliveTime的时间单位。
  5. workQueue:线程池的任务队列,线程池存放任务的队列,没有空闲线程执行新任务时,存储所有待执行任务。
  6. ThreadFactory:创建线程的工厂,通过此方法设置线程的优先级、线程命名规则以及线程类型(用户线程/守护线程)。
  7. RejectedExecutionHandler:拒绝策略,当线程池的任务超出线程池队列可以存储的最大值之后,执行的策略。

# 使用场景

线程池参数设置需要结合任务特性和系统资源综合判断,在避免资源浪费的同时防止任务堆积或线程竞争过度。

  1. CPU密集型任务(计算、排序)
    • 任务消耗CPU资源,线程执行时阻塞少
    • corePoolSize = CPU核心数 + 1 :减少线程切换开销。
  2. IO密集型任务(数据库、文件IO)
    • 任务大部分时间等待IO,CPU利用率低。
    • corePoolSize = CPU核心数 * 2 :利用空闲CPU处理更多任务,提高并发。

# 知识图解

  1. 线程池工作原理 image

# 知识扩展

  1. 扩展:
  • 线程池种类:
    1. ScheduledThreadPoolExecutor:定时执行任务,支持定时执行和周期执行。
    2. FixedThreadPool:固定大小线程池,线程数量固定,核心线程数和最大线程数相同,不会创建更多线程处理任务。
    3. CachedThreadPool:可缓存线程池,在于线程数是几乎可以无限增加(最大Integer.MAX_VALUE,2^31-1),线程闲置时会进行回收。
    4. SingleThreadExecutor:使用唯一的线程去执行任务,原理和FixedThreadPool一样,如果线程在执行任务时发生异常,会重新创建新线程执行后续任务,适合所有任务需要按顺序执行场景。
    5. SingleThreadScheduledExecutor:和ScheduledThreadPool线程池相似,属于其特例,内部只有一个线程。
  1. 面试官可能追问:
  • 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个任务,执行流程是什么?
    1. 前五个任务由核心线程直接执行
    2. 20个任务进入队列等待
    3. 剩余五个任务创建非核心线程执行
    4. 如果后面再提交任务,会执行拒绝策略

← 为什么要有线程池,线程太多会怎样? BIO、NIO、AIO的区别 →

评论

验证登录状态...

You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.