1.手动创建线程池 import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.ThreadPoolExecutor; /** * springboot自动配置 用于其他模块引用common包 * @author XiaoLei * @date 2023/2/3 13:38 */ @Configuration @Slf4j @ComponentScan("cn.com.") public class AutoConfiguration { //最大可用的CPU核数 //public static final int PROCESSORS = Runtime.getRuntime().availableProcessors(); //线程最大的空闲存活时间,单位为秒 public static final int KEEPALIVETIME = 60; //主线程等待子线程执行时间 public static final int AWAIT_TERMINATION_SECONDS = 60; //任务缓存队列长度 public static final int BLOCKINGQUEUE_LENGTH = 500; //线程池前缀 public static final String COMMUNITY_THREAD_POOL = "openapi-threadPool-"; /** * 线程池配置 * @param * @return java.util.concurrent.Executor * @author wliduo * @date 2019/2/15 14:44 */ @Bean(name = "threadPoolTaskExecutor") @Primary public ThreadPoolTaskExecutor threadPoolTaskExecutor() { //log.info("---------- 线程池开始加载 ----------"); ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor(); // 核心线程池大小 threadPoolTaskExecutor.setCorePoolSize(50); // 最大线程数 threadPoolTaskExecutor.setMaxPoolSize(200); // 队列容量 threadPoolTaskExecutor.setQueueCapacity(BLOCKINGQUEUE_LENGTH); // 线程最大的空闲存活时间,单位为秒 threadPoolTaskExecutor.setKeepAliveSeconds(KEEPALIVETIME); // 主线程等待子线程执行时间 threadPoolTaskExecutor.setAwaitTerminationSeconds(AWAIT_TERMINATION_SECONDS); // 线程名字前缀 threadPoolTaskExecutor.setThreadNamePrefix(COMMUNITY_THREAD_POOL); // RejectedExecutionHandler:当pool已经达到max-size的时候,如何处理新任务 /**这里如果设置无界队列,高并发情况下有可能会出现内存飙升,所以队列这里引入有界队列,使用 *LinkedBlockingQueue是因为这个队列效率高,按照FIFO优先级来处理,先放入队列的优先处理,但是这里就需要配置一个 * 拒绝策略,指定拒绝策略的CallerRunsPolicy * 该策略既不会抛弃任务也不会抛出异常,而是在调用execute()的线程中运行任务。比如我们在主线程中调用了execute(task)方法 * 但是这时workQueue已经满了,并且也不会创建的新的线程了。这时候将会在主线程中直接运行execute中的task。 * CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行 **/ threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 初始化 threadPoolTaskExecutor.initialize(); //log.info("---------- 线程池加载完成 ----------"); return threadPoolTaskExecutor; } }
2.需要使用的地方使用
@Resource(name = "threadPoolTaskExecutor") private ThreadPoolTaskExecutor threadPool;