Java线程池的工作原理

graph TD A[提交任务] --> B{核心线程池是否已满?} B -- 未满 --> C[创建核心线程执行任务] B -- 已满 --> D{任务队列是否已满?} D -- 未满 --> E[任务加入阻塞队列等待] D -- 已满 --> F{线程池是否达到最大线程数?} F -- 未达到 --> G[创建非核心线程执行任务] F -- 已达到 --> H[触发拒绝策略] classDef green fill:#D5E8D4,stroke:#82B366; classDef orange fill:#F8CECC,stroke:#B85450; classDef blue fill:#DAE8FC,stroke:#6C8EBF; class A,B,D,F blue class C,G green class H orange

工作原理详细流程:

  1. 任务提交

    • 当通过execute()submit()方法提交新任务时,线程池开始处理
  2. 核心线程检查

    • 检查当前运行的核心线程数是否小于corePoolSize
    • 若未满:创建新核心线程立即执行任务(即使有空闲线程也会创建新线程)
    • 若已满:进入下一步
  3. 任务队列检查

    • 尝试将任务加入阻塞队列(如LinkedBlockingQueue
    • 若队列未满:任务进入队列等待空闲线程处理
    • 若队列已满:进入下一步
  4. 最大线程数检查

    • 检查当前总线程数是否小于maximumPoolSize
    • 若未达到:创建临时非核心线程立即执行任务
    • 若已达到:进入拒绝流程
  5. 拒绝策略处理

    • 触发配置的拒绝策略(默认4种):
      • AbortPolicy:抛出RejectedExecutionException(默认策略)
      • CallerRunsPolicy:由提交任务的线程直接执行
      • DiscardPolicy:静默丢弃任务
      • DiscardOldestPolicy:丢弃队列最前面的任务并重试

关键组件说明:

组件 作用 配置参数
核心线程池 常驻线程,处理常规任务 corePoolSize
任务阻塞队列 缓存待处理任务 workQueue(如Array/LinkedBlockingQueue)
最大线程池 应急线程(临时创建) maximumPoolSize
线程存活时间 非核心线程空闲回收时间 keepAliveTime + unit
线程工厂 定制线程创建行为 ThreadFactory
拒绝策略 处理过载任务 RejectedExecutionHandler

工作特点:

  1. 线程复用:通过Worker类包装线程,循环从阻塞队列获取任务执行
  2. 资源回收:非核心线程空闲超过keepAliveTime后自动回收
  3. 优雅关闭
    • shutdown():停止接收新任务,继续处理队列任务
    • shutdownNow():尝试中断所有线程,返回未处理任务列表

最佳实践

  • IO密集型任务:建议 corePoolSize = CPU核数*2
  • CPU密集型任务:建议 corePoolSize = CPU核数+1
  • 使用ThreadPoolExecutor构造函数而非Executors工厂方法,避免资源耗尽风险