跳到正文
返回集合与并发

集合与并发 整理

线程池七个参数,放进一次任务提交里看

理解核心线程、队列、最大线程与拒绝策略之间的先后关系。

先回答:提交任务后,线程池会先扩线程,还是先排队?

在正常运行状态下,工作线程少于核心线程数时,通常先尝试创建线程;达到核心线程数后,先尝试进入队列;入队失败时,再尝试在最大线程数以内增加线程;仍无法接纳时执行拒绝策略。关闭状态与并发状态变化还会影响接纳结果。

七个参数分别管什么

  • corePoolSize:核心线程数量,是正常接纳流程中的重要分界。
  • maximumPoolSize:允许创建的最大工作线程数量。
  • keepAliveTime 与 unit:空闲线程的存活时长和时间单位。默认主要影响超过核心数量的线程,也可以允许核心线程超时。
  • workQueue:等待执行的任务队列,容量与队列实现直接影响线程扩展及排队行为。
  • threadFactory:创建线程,可设置清晰的名字、异常处理等。
  • handler:任务无法被线程池接纳时执行的拒绝处理器。

用一个有界队列的例子理解

ThreadPoolExecutor pool = new ThreadPoolExecutor(
    2, 4, 30, TimeUnit.SECONDS,
    new ArrayBlockingQueue<>(20),
    Executors.defaultThreadFactory(),
    new ThreadPoolExecutor.AbortPolicy()
);

这里用小数字说明参数关系,不是通用生产配置。如果前面的任务一直没有完成,线程数达到 2 后,新任务会优先入队;队列满后才尝试扩展到最多 4 个线程。

实际并发执行中,任务完成和队列消费会同时发生,不能只按“第几个任务”机械判断最终线程数。

面试里容易漏掉的两点

  • 使用可持续接纳任务的无界队列时,最大线程数通常不会像想象中那样发挥扩容作用,积压可能先吃掉内存。
  • CallerRunsPolicy 会把压力转移到提交线程;提交线程如果是请求线程,就会增加请求延迟。线程池已关闭时,它不会按正常运行时的方式执行任务。
  • 拒绝策略要与业务错误处理配合。不能不加判断地丢弃用户交易或余额相关任务。

参数该怎么定

先看 CPU 或 IO 特征、下游连接数量、任务耗时及可接受排队时间,再通过压测观察。公式只能作为起点,还应监控队列长度、拒绝次数、活跃线程和尾延迟。

延伸阅读

以上为个人整理。涉及版本实现和线上使用时,请结合对应文档与实际测试判断。