线程池处理任务的过程?
                           
天天向上
发布: 2025-04-26 19:05:07

原创
797 人浏览过

基于 JDK 官方 ThreadPoolExecutor 源码行为总结,标准的线程池处理任务流程如下:


1. 背景(线程池主要组成)

在执行任务前,线程池中有这些重要组件:

  • corePoolSize:核心线程数
  • maximumPoolSize:最大线程数
  • workQueue:阻塞任务队列
  • threadFactory:线程工厂
  • handler(RejectedExecutionHandler):拒绝策略

2. 任务提交

  • 调用 executor.execute(Runnable task)submit(Callable task) 提交任务。

3. 判断当前运行线程数量(workerCount)是否小于 corePoolSize

如果小于 corePoolSize:

✅ ➔ 直接创建一个新线程来执行这个任务。

  • 通过 threadFactory 创建线程并启动。
  • 新线程开始处理提交的任务。

注意:这个新建线程属于核心线程。)


如果大于等于 corePoolSize:

⏩ 进入下一步。


4. 尝试将任务加入工作队列(workQueue.offer)

如果队列未满(offer 成功):

✅ ➔ 把任务放进等待队列,等待已有线程来处理。

  • 核心线程会不断从队列中取任务执行。

如果队列已满(offer 失败):

⏩ 进入下一步。


5. 判断当前线程数(workerCount)是否小于 maximumPoolSize

如果小于 maximumPoolSize:

✅ ➔ 再创建一个新线程来执行这个任务。

(注意:这个新线程不是核心线程,是扩展线程(非核心线程)。)


如果等于或大于 maximumPoolSize:

⏩ 进入下一步。


6. 执行拒绝策略(RejectedExecutionHandler)

  • 当线程数已到上限、队列也满了,就调用拒绝策略。
  • 拒绝策略可以是:
  • 抛异常(默认:AbortPolicy)
  • 由提交任务的线程自己执行(CallerRunsPolicy)
  • 丢弃最新任务(DiscardPolicy)
  • 丢弃最老任务并重试(DiscardOldestPolicy)

小技巧:面试时加一句,一般重要业务还会加日志报警!


7. 任务执行

  • 核心线程或扩展线程从队列中不断拉取任务执行(Runnable.run())。
  • 任务执行完,线程继续取下一个任务。
  • 如果线程空闲超时(超过 keepAliveTime),且是非核心线程,就会被回收(销毁)。

线程池任务处理过程总结版

一张标准流程图

提交任务
    ↓
核心线程数 < corePoolSize?
    是 → 新建核心线程执行
    否 → 入队列
             ↓
      队列满了?
           是 → 当前线程数 < maximumPoolSize?
                    是 → 创建非核心线程执行
                    否 → 执行拒绝策略
           否 → 排队等待线程处理

小技巧:面试时可以再加一句总结

“线程池本质是通过合理的线程数控制和任务排队机制,最大化资源利用率,防止系统过载,同时保证任务尽可能快速被处理。”


更多详细内容请关注其他相关文章!

发表回复 0

Your email address will not be published. Required fields are marked *