验证码: 看不清楚,换一张 查询 注册会员,免验证
  • {{ basic.site_slogan }}
  • 打开微信扫一扫,
    您还可以在这里找到我们哟

    关注我们

ExecutorService线程池原理

阅读:788 来源:乙速云 作者:代码code

ExecutorService线程池原理

ExecutorService 是 Java 并发包(java.util.concurrent)中用于管理和调度线程池的核心接口,它屏蔽了线程的创建、销毁和调度细节,使开发者专注于“任务”本身。下面从整体架构、核心原理、关键实现类、任务执行流程、线程复用与生命周期几个方面系统讲解。


一、ExecutorService 的整体架构

Executor(顶层接口)
    |
    +-- ExecutorService(扩展接口)
           |
           +-- AbstractExecutorService(抽象实现)
                  |
                  +-- ThreadPoolExecutor(最常用实现)
                  |
                  +-- ScheduledThreadPoolExecutor(定时任务)

核心接口说明

  • Executor:只定义一个方法 execute(Runnable)
  • ExecutorService:在 Executor 基础上增加了
    • 任务提交(submit
    • 线程池关闭(shutdown / shutdownNow
    • 批量任务执行(invokeAll / invokeAny

二、ThreadPoolExecutor 的核心原理

1️⃣ 构造方法(核心)

public ThreadPoolExecutor(
    int corePoolSize,
    int maximumPoolSize,
    long keepAliveTime,
    TimeUnit unit,
    BlockingQueue workQueue,
    ThreadFactory threadFactory,
    RejectedExecutionHandler handler
)

参数含义

参数 含义
corePoolSize 核心线程数
maximumPoolSize 最大线程数
keepAliveTime 非核心线程空闲回收时间
workQueue 任务等待队列
threadFactory 线程工厂
handler 拒绝策略

三、线程池的任务执行流程(重点)

当一个任务被提交(executesubmit)时,流程如下:

✅ 执行流程图(逻辑)

提交任务
   |
   v
1. 核心线程是否已满?
   ├─ 否 → 创建核心线程执行
   └─ 是 ↓
2. 工作队列是否已满?
   ├─ 否 → 放入队列等待
   └─ 是 ↓
3. 线程数是否 < maximumPoolSize?
   ├─ 是 → 创建非核心线程执行
   └─ 否 ↓
4. 执行拒绝策略

四、线程是如何被“复用”的(核心原理)

关键点:线程不会执行完一个任务就结束

线程池中的线程大致逻辑如下(简化版):

while (task != null || (task = getTask()) != null) {
    task.run();
}

核心机制

  • 线程从 阻塞队列中获取任务
  • 如果队列为空:
    • 核心线程:阻塞等待
    • 非核心线程:超时等待,超时后销毁

线程复用 = 一个线程执行多个任务


五、核心线程 vs 非核心线程

类型 是否常驻 回收条件
核心线程 默认不回收(可配置)
非核心线程 空闲超过 keepAliveTime

核心线程即使空闲,也不会被回收(除非调用 allowCoreThreadTimeOut(true)


六、任务队列(BlockingQueue)

常见队列类型:

队列 特点
LinkedBlockingQueue 无界(默认 Integer.MAX_VALUE)
ArrayBlockingQueue 有界
SynchronousQueue 不存储任务,直接交付
PriorityBlockingQueue 支持优先级

队列的影响

  • 无界队列:不会创建非核心线程
  • 有界队列:更容易触发线程扩容和拒绝策略

七、拒绝策略(RejectedExecutionHandler)

当线程池和队列都满时触发:

策略 行为
AbortPolicy(默认) 抛异常
CallerRunsPolicy 调用者线程执行
DiscardPolicy 直接丢弃
DiscardOldestPolicy 丢弃最老任务

八、ExecutorService 中的 submit 与 execute 区别

方法 返回值 是否支持 Callable
execute
submit Future
Future future = executor.submit(() -> "OK");
String result = future.get();

九、线程池的生命周期

线程池状态(内部用 ctl 变量表示):

RUNNING → SHUTDOWN → STOP → TIDYING → TERMINATED

关闭方法

  • shutdown():不再接受新任务,执行完已有任务
  • shutdownNow():尝试中断正在执行的任务

十、常见的 Executors 工厂方法(底层仍是 ThreadPoolExecutor)

方法 特点
newFixedThreadPool 固定线程数
newCachedThreadPool 线程可无限增长
newSingleThreadExecutor 单线程
newScheduledThreadPool 定时任务

⚠️ 生产环境不推荐直接使用 Executors,原因:

  • 队列无界
  • 线程数不可控
  • 容易 OOM

✅ 推荐使用 ThreadPoolExecutor 手动配置


十一、一句话总结

ExecutorService 线程池的本质是:用少量线程 + 阻塞队列 + 任务复用机制,避免频繁创建/销毁线程,提高系统性能和资源利用率。

如果你愿意,我可以:

  • 画一张更直观的流程图
  • 结合源码逐行讲解 execute() 方法
  • 用实际业务场景解释如何合理配置线程池参数
分享到:
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: hlamps#outlook.com (#换成@)。
相关文章
{{ v.title }}
{{ v.description||(cleanHtml(v.content)).substr(0,100)+'···' }}
你可能感兴趣
推荐阅读 更多>