参考网上资源整理springboot线程池配置类:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import javax.annotation.PreDestroy;
import java.util.concurrent.ThreadPoolExecutor;
/**
* <p>Title:ThreadPoolConfig</p>
*
* @description: 线程池配置类
* @author: ywj
* @create: 2023-09-26 09:38
* SpringBoot 提供了注解 @Async 来使用线程池, 具体使用方法如下:
* 1.在启动类(配置类)添加@EnableAsync来开启线程池
* 2.在需要开启子线程的方法上添加注解 @Async
*
* 使用注意事项:
* 1.注解的方法必须是 public 方法。
* 2.方法一定要从另一个类中调用,也就是从类的外部调用,类的内部调用是无效的,因为@Transactional和@Async注解的实现都是基于Spring的AOP,
* 而AOP的实现是基于动态代理模式实现的。那么注解失效的原因就很明显了,有可能因为调用方法的是对象本身而不是代理对象,因为没有经过 Spring 容器。
* 3.异步方法使用注解 @Async 的返回值只能为 void 或者 Future。
*
* 线程池处理步骤:
* 第一步:查看核心线程池是否已满,不满就创建一条线程执行任务,否则执行第二步。
* 第二步:查看任务队列是否已满,不满就将任务存储在任务队列中,否则执行第三步。
* 第三步:查看线程池是否已满,即就是是否达到最大线程池数,不满就创建一条线程执行任务,否则就按照策略处理无法执行的任务。
*/
@Configuration
public class ThreadPoolConfig {
//获得Java虚拟机可用的处理器个数 + 1
private static final int THREADS = Runtime.getRuntime().availableProcessors() + 1;
@Value("${async.executor.thread.core_pool_size:0}")
public static int corePoolSizeConfig;
// 核心线程池大小
public static int corePoolSize = corePoolSizeConfig == 0 ? THREADS : corePoolSizeConfig;
// 最大可创建的线程数
//@Value("${async.executor.thread.max_pool_size}")
private int maxPoolSize = 2 * THREADS;;
// 队列最大长度
//@Value("${async.executor.thread.queue_capacity}")
private int queueCapacity = 1024;
// 线程池维护线程所允许的空闲时间
//@Value("${async.executor.thread.keep_alive_seconds}")
private int keepAliveSeconds = 300;
//线程池名前缀
//@Value("${async.executor.thread.threadNamePrefix}")
private static final String threadNamePrefix = "Cims-Async-Service-";
@Bean(name = "threadPoolTaskExecutor")
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setMaxPoolSize(maxPoolSize);
executor.setCorePoolSize(corePoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setKeepAliveSeconds(keepAliveSeconds);
executor.setThreadNamePrefix(threadNamePrefix);
/**
* 线程池对拒绝任务(无线程可用)的处理策略
* RejectedExectutionHandler 参数字段用于配置绝策略,常用拒绝策略如下:
* AbortPolicy:用于被拒绝任务的处理程序,它将抛出RejectedExecutionException
* CallerRunsPolicy:用于被拒绝任务的处理程序,它直接在execute方法的调用线程中运行被拒绝的任务,即由调用线程(提交任务的线程)处理该任务
* DiscardOldestPolicy:用于被拒绝任务的处理程序,它放弃最旧的未处理请求,然后重试execute
* DiscardPolicy:用于被拒绝任务的处理程序,默认情况下它将丢弃被拒绝的任务
**/
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 初始化
executor.initialize();
return executor;
}
@PreDestroy
public void destroy() {
ThreadPoolTaskExecutor executor = threadPoolTaskExecutor();
executor.shutdown();
}
}