SpringBoot的线程池的自动注入

kyang MVP++

本文适合会基本springboot工程创建的人

在这里插入图片描述

配置文件

pom.xml要导入的包

1
2
3
4
5
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>

application.yml

设置你需要的配置

1
2
3
4
5
6
7
8
9
thread:
pool:
executor:
config:
core-pool-size: 20
max-pool-size: 200
keep-alive-time: 10
block-queue-size: 5000
policy: CallerRunsPolicy

读取配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "thread.pool.executor.config", ignoreInvalidFields = true)
public class ThreadPoolConfigProperties {

/** 核心线程数 */
private Integer corePoolSize = 20;
/** 最大线程数 */
private Integer maxPoolSize = 200;
/** 最大等待时间 */
private Long keepAliveTime = 10L;
/** 最大队列数 */
private Integer blockQueueSize = 5000;

private String policy = "AbortPolicy";

}

prefix

读取文件中的前缀

ignoreInvalidFields字段含义

ignoreInvalidFields: 当这个属性设置为true时,Spring会忽略配置文件中那些与配置类字段不匹配的属性。这意味着,如果配置文件中存在与配置类字段不存在的属性,Spring不会抛出异常,而是忽略这些属性。

Policy属性

  • AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
  • DiscardPolicy:直接丢弃任务,但是不会抛出异常
  • DiscardOldestPolicy:将最早进入队列的任务删除,之后再尝试加入队列的任务被拒绝
  • CallerRunsPolicy:如果任务添加线程池失败,那么主线程自己执行该任务

创建实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/** 开启异步 */
@EnableAsync
@Configuration
/** 填写之前读取配置那个类的类名 */
@EnableConfigurationProperties(ThreadPoolConfigProperties.class)
public class ThreadPoolConfig {

@Bean
@ConditionalOnMissingBean(ThreadPoolExecutor.class)
public ThreadPoolExecutor threadPoolExecutor(ThreadPoolConfigProperties properties) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
// 实例化策略
RejectedExecutionHandler handler;
switch (properties.getPolicy()){
case "DiscardPolicy":
handler = new ThreadPoolExecutor.DiscardPolicy();
break;
case "DiscardOldestPolicy":
handler = new ThreadPoolExecutor.DiscardOldestPolicy();
break;
case "CallerRunsPolicy":
handler = new ThreadPoolExecutor.CallerRunsPolicy();
break;
default:
handler = new ThreadPoolExecutor.AbortPolicy();
break;
}
// 创建线程池
return new ThreadPoolExecutor(properties.getCorePoolSize(),
properties.getMaxPoolSize(),
properties.getKeepAliveTime(),
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(properties.getBlockQueueSize()),
Executors.defaultThreadFactory(),
handler);
}

}

@ConditionalOnMissingBean的作用

  1. 条件@ConditionalOnMissingBean 注解检查Spring容器中是否已经存在具有指定名称或类型的Bean。如果存在,则不会创建新的Bean。
  2. 名称:可以通过 name 属性指定Bean的名称。如果指定了名称,则只有当容器中不存在具有该名称的Bean时,才会创建新的Bean。
  3. 类型:可以通过 type 属性指定Bean的类型。如果指定了类型,则只有当容器中不存在该类型的Bean时,才会创建新的Bean。
  4. 组合条件:可以同时使用 nametype 属性来组合条件,确保只有同时满足名称和类型条件时才会创建Bean。
  5. 依赖条件:还可以使用 dependentOnBean 属性来指定一个依赖的Bean名称,只有当依赖的Bean存在时,才会创建新的Bean。

ThreadPoolExecutor参数含义

  • properties.getCorePoolSize(): 这个参数表示线程池的基本大小,即在没有任务执行时保持空闲的线程数量。
    含义: 在创建线程池时,会首先创建这个数量的线程。如果这些线程都忙于处理任务,那么线程池会根据需要创建更多线程,但不会超过最大线程数。

  • properties.getMaxPoolSize(): 这个参数表示线程池最大线程数。
    含义: 当所有核心线程都在执行任务时,线程池会创建额外的线程,直到达到这个最大值。超过这个数的线程会被拒绝执行。

  • properties.getKeepAliveTime(): 这个参数表示当线程没有任务执行时,保持空闲的最长时间。
    含义: 如果空闲线程超过这个时间,则线程会被终止。如果这个值设置为Long.MAX_VALUE,则空闲线程会一直保持活动状态。

  • TimeUnit.SECONDS: 这个参数表示keepAliveTime的时间单位。
    含义: 它指定了keepAliveTime参数的时间单位,在这个例子中是秒。

  • new LinkedBlockingQueue<>(properties.getBlockQueueSize()): 这个参数表示用于在线程池任务队列中存储等待执行的任务。
    含义: LinkedBlockingQueue是一个线程安全的无界队列,它适用于生产者-消费者场景。blockQueueSize是队列的容量,表示队列可以存储的最大任务数量。

  • Executors.defaultThreadFactory(): 这个参数表示线程池中线程的工厂。
    含义: Executors.defaultThreadFactory()提供默认的线程工厂,用于创建线程。默认线程工厂创建的线程没有特别的名称或组,并且具有非守护状态。

  • handler: 这个参数表示线程池中的任务拒绝策略。
    含义: 当线程池达到最大大小,无法继续添加新任务时,会调用拒绝策略。handler可以是ThreadPoolExecutor提供的四种拒绝策略。(上面有说)

导入使用

1
2
3
// 在你需要的地方导入,然后就可以使用了
@Autowired
ThreadPoolExecutor executor;
  • 标题: SpringBoot的线程池的自动注入
  • 作者: kyang
  • 创建于 : 2025-07-11 16:56:12
  • 更新于 : 2025-07-11 16:56:12
  • 链接: https://blog.kyang.top/2025/07/11/SpringBoot线程池的自动化注入/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论