1. 核心参数详解

ThreadPoolExecutor 的标准构造函数包含 7 个参数,面试时建议按顺序清晰阐述:

  1. corePoolSize (核心线程数)
    • 含义:线程池维护的最小线程数量。即使这些线程处于空闲状态,也不会被销毁(除非设置了 allowCoreThreadTimeOut)。
    • 作用:保证基本的并发处理能力。
  2. maximumPoolSize (最大线程数)
    • 含义:线程池允许创建的最大线程数量。
    • 作用:控制资源消耗上限,防止无限制创建线程耗尽 CPU/内存。
  3. keepAliveTime (存活时间)
    • 含义:当线程数大于核心线程数时,多余的空闲线程在终止前等待新任务的最长时间。
    • 作用:动态回收线程资源,降低系统开销。
  4. unit (时间单位)
    • 含义keepAliveTime 的时间单位(如秒、毫秒)。
  5. workQueue (任务队列)
    • 含义:用于保存等待执行任务的阻塞队列。
    • 常见类型
      • ArrayBlockingQueue:有界,适合防止资源耗尽。
      • LinkedBlockingQueue:默认无界(需小心 OOM),吞吐量通常更高。
      • SynchronousQueue:不存储元素,直接移交,适合高并发短任务。
  6. threadFactory (线程工厂)
    • 含义:用于创建新线程的工厂。
    • 作用:建议自定义,设置有意义的线程名称(如 order-service-pool-%d),这对生产环境排查日志至关重要。
  7. handler (拒绝策略)
    • 含义:当队列满且线程达到最大值时,对新任务的处理策略。
    • JDK默认策略
      • AbortPolicy:抛异常(默认)。
      • CallerRunsPolicy:调用者自己运行(既不丢弃任务,又能减缓提交速度)。
      • DiscardPolicy:直接丢弃。
      • DiscardOldestPolicy:丢弃队列中最老的任务。

2. 进阶:参数配置最佳实践

面试官常追问:“这些参数该怎么设置?”

  • CPU 密集型任务(如加密、计算):
    • 配置:N + 1 (N 为 CPU 核心数)。
    • 理由:线程主要在计算,减少上下文切换。
  • I/O 密集型任务(如读写库、接口调用):
    • 配置:2NN / (1 - 阻塞系数)
    • 理由:线程大部分时间在等待 I/O,需要更多线程来利用 CPU。

3. 总结

回答总结: “线程池包含核心线程数、最大线程数、空闲存活时间、时间单位、任务队列、线程工厂和拒绝策略这 7 个参数。配置时需根据业务类型(CPU密集 vs IO密集)合理设置大小,并强烈建议使用有界队列自定义线程工厂(命名),以确保系统的稳定性和可维护性。”