913 字
5 分钟
线程池主要参数有哪些?

线程池主要参数有哪些?#

线程池有 7 个参数,需要重点关注corePoolSize、maximumPoolSize、workQueue、handler 这四个。 imageasdas 线程池参数 ①、corePoolSize 定义了线程池中的核心线程数量。即使这些线程处于空闲状态,它们也不会被回收。这是线程池保持在等待状态下的线程数。 ②、maximumPoolSize 线程池允许的最大线程数量。当工作队列满了之后,线程池会创建新线程来处理任务,直到线程数达到这个最大值。 ③、keepAliveTime 非核心线程的空闲存活时间。如果线程池中的线程数量超过了 corePoolSize,那么这些多余的线程在空闲时间超过 keepAliveTime 时会被终止。 ④、unit keepAliveTime 参数的时间单位:

  • TimeUnit.DAYS; 天
  • TimeUnit.HOURS; 小时
  • TimeUnit.MINUTES; 分钟
  • TimeUnit.SECONDS; 秒
  • TimeUnit.MILLISECONDS; 毫秒
  • TimeUnit.MICROSECONDS; 微秒
  • TimeUnit.NANOSECONDS; 纳秒

⑤、workQueue 用于存放待处理任务的阻塞队列。当所有核心线程都忙时,新任务会被放在这个队列里等待执行。 ⑥、threadFactory 一个创建新线程的工厂。它用于创建线程池中的线程。可以通过自定义 ThreadFactory 来给线程池中的线程设置有意义的名字,或设置优先级等。 ⑦、handler 拒绝策略 RejectedExecutionHandler,定义了当线程池和工作队列都满了之后对新提交的任务的处理策略。常见的拒绝策略包括抛出异常、直接丢弃、丢弃队列中最老的任务、由提交任务的线程来直接执行任务等。 它们之间的关系如下: ①、corePoolSize 和 maximumPoolSize 共同定义了线程池的规模。

  • 当提交的任务数不足以填满核心线程时,线程池只会创建足够的线程来处理任务。
  • 当任务数增多,超过核心线程的处理能力时,任务会被加入 workQueue。
  • 如果 workQueue 已满,而当前线程数又小于 maximumPoolSize,线程池会尝试创建新的线程来处理任务。

②、keepAliveTime 和 unit 决定了非核心线程可以空闲存活多久。这会影响了线程池的资源回收策略。 ③、workQueue 的选择对线程池的行为有重大影响。不同类型的队列(如无界队列、有界队列)会导致线程池在任务增多时的反应不同。 ④、handler 定义了线程池的饱和策略,即当线程池无法接受新任务时的行为。决定了系统在极限情况下的表现。

举个例子说一下这些参数的变化#

假设一个场景,线程池的配置如下:

corePoolSize = 5
maximumPoolSize = 10
keepAliveTime = 60秒
workQueue = LinkedBlockingQueue(容量为100)
默认的threadFactory
handler = ThreadPoolExecutor.AbortPolicy()

场景一:当系统启动后,逐渐有 10 个任务提交到线程池。

  • 前 5 个任务会立即执行,因为它们会占用所有的核心线程。
  • 随后的 5 个任务会被放入工作队列中等待执行。

场景二:如果此时再有 100 个任务提交到线程池。

  • 工作队列已满,线程池会创建额外的线程来执行这些任务,直到线程总数达到 maximumPoolSize(10 个线程)。
  • 如果任务继续增加,超过了工作队列和最大线程数的限制,新来的任务将会根据拒绝策略(AbortPolicy)被拒绝,抛出 RejectedExecutionException 异常。

场景三:如果任务突然减少,只有少量的任务需要执行: 核心线程会一直运行,而超出核心线程数的线程,如果空闲时间超过 keepAliveTime,将会被终止,直到线程池的线程数减少到 corePoolSize。

线程池主要参数有哪些?
作者
强人自传
发布于
2023-08-16
许可协议
CC BY-NC-SA 4.0