Springboot与线程池整合(异步处理)

2022-07-14 11:36:26

一、线程池基本配置

1.1 配置文件

#springboot线程池配置task:pool:corePoolSize:10maxPoolSize:20keepAliveSeconds:300queueCapacity:50

1.2 基本配置类

@Data@Component@ConfigurationProperties(prefix="task.pool")publicclassTaskThreadPoolConfig{/** 核心线程数 */privateint corePoolSize;/** 最大线程数 */privateint maxPoolSize;/** 线程空闲时间 */privateint keepAliveSeconds;/** 任务队列容量(阻塞队列) */privateint queueCapacity;}

二、线程池配置

2.1 重写默认线程池

@Slf4j@Component@EnableAsyncpublicclassOverrideDefaultThreadPoolConfigimplementsAsyncConfigurer{@AutowiredprivateTaskThreadPoolConfig config;@OverridepublicExecutorgetAsyncExecutor(){ThreadPoolTaskExecutor executor=newThreadPoolTaskExecutor();// 核心线程池大小
    executor.setCorePoolSize(config.getCorePoolSize());// 最大线程数
    executor.setMaxPoolSize(config.getMaxPoolSize());// 队列容量
    executor.setQueueCapacity(config.getQueueCapacity());// 活跃时间
    executor.setKeepAliveSeconds(config.getKeepAliveSeconds());// 线程名字前缀
    executor.setThreadNamePrefix("default-thread-");/*
     当poolSize已达到maxPoolSize,如何处理新任务(是拒绝还是交由其它线程处理)
     CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行
    */
    executor.setRejectedExecutionHandler(newThreadPoolExecutor.CallerRunsPolicy());
    executor.initialize();return executor;}/**
   * 异步任务中异常处理
   *
   * @return
   */@OverridepublicAsyncUncaughtExceptionHandlergetAsyncUncaughtExceptionHandler(){return(ex, method, params)->{
      log.error("=========================="+ ex.getMessage()+"=======================", ex);
      log.error("exception method:"+ method.getName());};}

2.2 创建自定义线程池

@Configuration@EnableAsyncpublicclassCustomizeThreadPoolConfig{@AutowiredprivateTaskThreadPoolConfig config;@Bean("customizeThreadPool")publicExecutordoConfigCustomizeThreadPool(){ThreadPoolTaskExecutor executor=newThreadPoolTaskExecutor();// 核心线程池大小
    executor.setCorePoolSize(config.getCorePoolSize());// 最大线程数
    executor.setMaxPoolSize(config.getMaxPoolSize());// 队列容量
    executor.setQueueCapacity(config.getQueueCapacity());// 活跃时间
    executor.setKeepAliveSeconds(config.getKeepAliveSeconds());// 线程名字前缀
    executor.setThreadNamePrefix("customize-thread-");/*
     当poolSize已达到maxPoolSize,如何处理新任务(是拒绝还是交由其它线程处理)
     CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行
    */
    executor.setRejectedExecutionHandler(newThreadPoolExecutor.CallerRunsPolicy());
    executor.initialize();return executor;}}

三、使用springboot默认的线程池

3.1 通过@Async注解调用

  • 第一步:在Application启动类上面加上@EnableAsync

@SpringBootApplication@EnableAsyncpublicclassThreadpoolApplication{publicstaticvoidmain(String[] args){SpringApplication.run(ThreadpoolApplication.class, args);}}
  • 第二步:在需要异步执行的方法上加上@Async注解

@ServicepublicclassAsyncTest{protected final Logger logger= LoggerFactory.getLogger(this.getClass());// 使用默认线程池
	@Asyncpublicvoidhello(String name){//这里使用logger 方便查看执行的线程是什么
        logger.info("默认线程池:异步线程启动 started."+name);}// 使用自定义线程池
	@Async("customizeThreadPool")publicvoidhi(String name){//这里使用logger 方便查看执行的线程是什么
        logger.info("自定义线程池:异步线程启动 started."+name);}}
  • 第三步:测试类进行测试验证

    @Autowired
    AsyncTest asyncTest;
    @TestvoidcontextLoads() throws InterruptedException{
        asyncTest.hello("afsasfasf");//一定要休眠 不然主线程关闭了,子线程还没有启动
        Thread.sleep(1000);}

3.2 直接调用ThreadPoolTaskExecutor

直接注入ThreadPoolTaskExecutor

@SpringBootTestclassThreadPoolApplicationTests{protectedfinalLogger logger=LoggerFactory.getLogger(this.getClass());@AutowiredAsyncTest asyncTest;@AutowiredprivateThreadPoolTaskExecutor threadPoolTaskExecutor;@TestvoidasyncTest0()throwsInterruptedException{
        asyncTest.hello("async注解创建");
        threadPoolTaskExecutor.submit(newThread(()->{
            logger.info("threadPoolTaskExecutor 创建线程");}));//一定要休眠 不然主线程关闭了,子线程还没有启动Thread.sleep(1000);}}

以上,请参考,谢谢!

  • 作者:投身大海的魚
  • 原文链接:https://blog.csdn.net/weixin_41668084/article/details/118662035
    更新时间:2022-07-14 11:36:26