Spring-boot 使用线程池
2021-01-20 本文已影响0人
桃子家的二哈
线程池就是首先创建一些线程,它们的集合称为线程池。使用线程池可以很好地提高性能,线程池在系统启动时即创建大量空闲的线程,程序将一个任务传给线程池,线程池就会启动一条线程来执行这个任务,执行结束以后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务。
四种常用的线程池
- Executors.newCacheThreadPool():可缓存线程池
- Executors.newFixedThreadPool(int n):创建一个可重用固定个数的线程池,以共享的无界队列方式来运行这些线程。
- Executors.newScheduledThreadPool(int n):创建一个定长线程池,支持定时及周期性任务执行
- Executors.newSingleThreadExecutor():创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
spring-boot 新建自定义线程池
我们的需要新建一个Configuration 类来配置我们的线程池参数。
package com.uhi.applyment4sub.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @author adoreFT
* @date 2021/01/13 16:19
* @Description: uhi线程池配置类
*/
@Configuration
@EnableAsync
public class ThreadPoolTaskConfig {
/**
* 默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,
* 当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中;
* 当队列满了,就继续创建线程,当线程数量大于等于maxPoolSize后,开始使用拒绝策略拒绝
*/
/**
* 核心线程数(默认线程数)
*/
private static final int corePoolSize = 5;
/**
* 最大线程数
*/
private static final int maxPoolSize = 30;
/**
* 允许线程空闲时间(单位:默认为秒)
*/
private static final int keepAliveTime = 30;
/**
* 缓冲队列大小
*/
private static final int queueCapacity = 10000;
/**
* 线程池名前缀
*/
private static final String threadNamePrefix = "hdl-uhi-service-";
@Bean("taskExecutor") // bean的名称,默认为首字母小写的方法名
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setKeepAliveSeconds(keepAliveTime);
executor.setThreadNamePrefix(threadNamePrefix);
// 线程池对拒绝任务的处理策略
// CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 初始化
executor.initialize();
return executor;
}
}
其中我们的静态参数也可以放在配置文件中,我这边使用的 yml 配置文件:
#线程池配置参数
task:
pool:
corePoolSize: 5 #设置核心线程数
maxPoolSize: 20 #设置最大线程数
keepAliveSeconds: 300 #设置线程活跃时间(秒)
queueCapacity: 50 #设置队列容量
上边的这里需要用注解来引用对象方式实现:
@ConfigurationProperties(prefix = "task.pool")
注解解释
@Configuration用于定义配置类,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。
@EnableAsync开始对异步任务的支持
@Async 定义一个线程任务
@Bean 产生一个Bean对象,然后这个Bean对象交给Spring管理 (如上:@Bean("taskExecutor"))
线程使用
- 引用线程池
@Autowired
@Qualifier(value = "taskExecutor")
private ThreadPoolTaskExecutor poolTaskExecutor;
- 异步方法定义
//根据组织做数据更新以及新增删除
for (UhiDdOrgContrast orgContrast : orgContrastList) {
poolTaskExecutor.execute(() -> {
userPackAgeData(token, orgContrast);
});
}
userPackAgeData 方法添加指定线程名:
@Async("taskExecutor")
public void userPackAgeData(String token, UhiDdOrgContrast orgContrast) {
//业务代码实现
// XXXX
}