【Java 线程池】记录

线程池关键参数

参数名 作用描述 默认值(无参构造) 说明
corePoolSize‌ 核心线程数 0 任务队列满时创建新线程的阈值
maximumPoolSize‌ 最大线程数 Integer.MAX_VALUE 核心线程数满后允许的最大线程数
keepAliveTime‌ ‌空闲线程存活时间 0 线程空闲超过此时间被回收(仅适用于 > corePoolSize 的线程)
unit‌ 时间单位 TimeUnit.MILLISECONDS keepAliveTime 的时间单位
workQueue‌ ‌任务队列 SynchronousQueue(无界队列) 任务缓冲区,支持多种队列策略(如 LinkedBlockingQueue)
threadFactory‌ ‌线程工厂 默认工厂 自定义线程创建逻辑(如设置线程名、优先级)
handler‌ ‌拒绝策略 AbortPolicy(抛出异常) 当线程池满载时处理拒绝任务(如 CallerRunsPolicy、DiscardPolicy)

关键参数说明

  1. 核心线程数(corePoolSize)‌
    • 任务队列满时创建新线程的阈值。
    • 若任务量稳定,建议设置为 CPU 核心数(如
      Runtime.getRuntime().availableProcessors())。
  2. ‌最大线程数(maximumPoolSize)‌
    • 核心线程数满后允许的最大线程数。
    • 无界队列时,此参数无效(如 LinkedBlockingQueue)。
  3. 空闲线程存活时间(keepAliveTime)‌
    • 空闲线程超过此时间被回收(仅适用于 > corePoolSize 的线程)。
    • 通过 allowCoreThreadTimeOut(true) 可使核心线程也受此限制。
  4. 任务队列(workQueue)‌
    • 常用队列类型:
      • ArrayBlockingQueue:有界队列,防止资源耗尽。
      • LinkedBlockingQueue:无界队列(实际最大容量 Integer.MAX_VALUE)。
      • SynchronousQueue:直接传递任务,无存储。
  5. 拒绝策略(handler)‌
    • 当线程池满载时处理拒绝任务:

      策略类型 行为描述 适用场景 代码示例
      AbortPolicy 抛出 RejectedExecutionException 异常(默认) 适用于 严格控制任务提交,避免资源耗尽 new ThreadPoolExecutor(..., new ThreadPoolExecutor.AbortPolicy())
      CallerRunsPolicy 由调用线程执行任务,阻塞提交线程 适用于 降级机制,防止系统崩溃 new ThreadPoolExecutor(..., new ThreadPoolExecutor.CallerRunsPolicy())
      DiscardPolicy 直接丢弃任务,不抛出异常 任务可丢弃场景,如日志记录 new ThreadPoolExecutor(..., new ThreadPoolExecutor.DiscardPolicy())
      DiscardOldestPolicy 丢弃队列中最老任务,重试提交 优先保留新任务场景 new ThreadPoolExecutor(..., new ThreadPoolExecutor.DiscardOldestPolicy())

代码示例

创建线程池

java 复制代码
@Configuration
public class ThreadPoolConfig {

    // 核心线程数 20
    @Value("${lease.thread.core-size:20}")
    private Integer coreSize;

    // 最大线程数 100
    @Value("${lease.thread.max-size:100}")
    private Integer maxSize;

    // 空闲线程存活时间 10
    @Value("${lease.thread.keep-alive-time:10}")
    private Integer keepAliveTime;

    @Bean
    public ThreadPoolExecutor threadPoolExecutor() {
        return new ThreadPoolExecutor(coreSize,
                maxSize,
                keepAliveTime,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(100000),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
    }
}

使用线程池

java 复制代码
@Slf4j
@RestController
@RequestMapping("/hello")
public class Hello {

	@Resource
	ThreadPoolExecutor threadPoolExecutor;

	@RequestMapping("/world")
    public void world(HttpServletRequest request, UserDTO userDTO) throws Exception {
    	try {
		    CompletableFuture.runAsync(()-> {
		        try {
		            log.info("处理业务逻辑");
		        } catch (IOException e) {
		            throw new RuntimeException(e);
		        }},threadPoolExecutor);
		} catch (Exception e) {
		    log.error("处理业务逻辑异常!", e);
		}
    }
}

CompletableFuture类中还有其它的方法:

  1. runAsync - 异步执行无返回值的任务
  2. supplyAsync - 异步执行有返回值的任务
  3. thenApply - 对异步任务的结果进行转换
  4. thenAccept - 消费异步任务的结果
  5. thenCompose - 将多个异步任务串联执行
  6. exceptionally - 处理异步任务中的异常
  7. whenComplete - 在异步任务完成时执行回调
  8. allOf - 等待所有异步任务完成
  9. anyOf - 等待任意一个异步任务完成

总结

流程梳理

当线程池配置为‌核心线程数20、最大线程数100、空闲线程存活时间10秒‌时,新任务提交后的执行流程可拆解为以下‌5个关键阶段‌,每个阶段需结合线程池参数与任务队列状态判断:

1. 核心线程阶段(核心线程数内优先创建线程)

  • 条件‌ :线程池中‌存活线程数 < 20‌(核心线程数)。
  • 动作‌ :无论核心线程是否空闲,线程池都会‌创建一个新线程‌执行任务。
  • 逻辑‌:核心线程是"常驻线程",默认不会因空闲被销毁(除非allowCoreThreadTimeOut=true,但此处未开启,因此核心线程始终存活)。

2. 任务队列阶段(核心线程满后,任务先入队列等待)

  • 条件‌ :线程池中‌存活线程数 ≥ 20‌(核心线程数已满)。
  • 动作‌ :线程池会将新任务‌放入任务队列‌(如LinkedBlockingQueue等阻塞队列)中等待执行。 ‌
  • 逻辑‌:核心线程满时,优先让任务排队,避免直接创建非核心线程(临时线程),减少线程创建的开销。

3. 非核心线程阶段(队列满后,创建临时线程到最大线程数)

  • 条件‌ :任务队列‌已满‌ (无剩余空间容纳新任务),且线程池中‌存活线程数 < 100‌(最大线程数)。
  • 动作‌ :线程池会‌创建非核心线程‌(临时线程)执行新任务,直到存活线程数达到100。
  • 逻辑‌:队列满时,判断是否有空闲的核心线程,如果有就用空闲的核心线程,否则线程池会突破核心线程数限制,创建临时线程处理突发任务,但临时线程的空闲时间超过10秒后会被销毁(由keepAliveTime=10s控制)。

4. 拒绝策略触发阶段(队列+线程均满时,执行拒绝策略)

  • 条件‌ :任务队列‌已满‌ ,且线程池中‌存活线程数 = 100‌(最大线程数已满)。
  • 动作‌ :新任务无法被线程池接收,触发‌拒绝策略‌(如默认的AbortPolicy会抛出RejectedExecutionException异常)。
  • 逻辑‌:当线程池和队列的容量都被耗尽时,拒绝策略用于优雅降级,防止系统因资源耗尽崩溃。

5. 空闲线程回收阶段(临时线程空闲超时后被销毁)

  • 条件‌ :非核心线程(临时线程)‌空闲时间超过10秒‌(keepAliveTime=10s)。
  • 动作‌ :线程池会‌销毁该临时线程‌,释放系统资源。
  • 逻辑‌:临时线程的空闲时间由keepAliveTime控制,超过10秒后会被回收,避免资源浪费(核心线程因allowCoreThreadTimeOut=false不会被回收)。

流程总结(以时间线为例)

  1. 提交任务 → 核心线程数<20 → 创建核心线程执行任务。
  2. 核心线程数≥20 → 任务入队列等待。
  3. 队列满且线程数<100 → 创建非核心线程执行任务(在这之前会判断是否有空闲的核心线程,如果有就用空闲的核心线程)。
  4. 队列满且线程数=100 → 触发拒绝策略。
  5. 临时线程空闲超10秒 → 回收临时线程。

通过以上5个阶段的联动,线程池实现了‌"核心线程常驻+任务队列缓冲+临时线程弹性扩展+拒绝策略兜底+空闲线程回收"‌的完整闭环,平衡了任务响应速度与系统资源消耗。

相关推荐
大学生资源网2 小时前
基于springboot的唐史文化管理系统的设计与实现源码(java毕业设计源码+文档)
java·spring boot·课程设计
guslegend3 小时前
SpringSecurity源码剖析
java
roman_日积跬步-终至千里3 小时前
【人工智能导论】02-搜索-高级搜索策略探索篇:从约束满足到博弈搜索
java·前端·人工智能
大学生资源网4 小时前
java毕业设计之儿童福利院管理系统的设计与实现(源码+)
java·开发语言·spring boot·mysql·毕业设计·源码·课程设计
JasmineWr4 小时前
JVM栈空间的使用和优化
java·开发语言
Hello.Reader4 小时前
Flink SQL DELETE 语句批模式行级删除、连接器能力要求与实战避坑(含 Java 示例)
java·sql·flink
爱笑的眼睛114 小时前
从 Seq2Seq 到 Transformer++:深度解构与自构建现代机器翻译核心组件
java·人工智能·python·ai
Spring AI学习4 小时前
Spring AI深度解析(10/50):多模态应用开发实战
java·spring·ai
qq_12498707537 小时前
重庆三峡学院图书资料管理系统设计与实现(源码+论文+部署+安装)
java·spring boot·后端·mysql·spring·毕业设计