8月24

SpringBoot项目定时任务阻塞的问题配置线程池解决

| |
11:09编程杂谈  From: 本站原创
首先经过了解查看源码,@Scheduled是单线程的,如果有多个定时任务,势必需要前一个任务执行完才会执行后面的任务
点击在新窗口中浏览此图片

所以我们有三种方法解决定时任务线程池配置解决多个定时任务阻塞问题
1、重写SchedulingConfigurer#configureTasks(),直接实现SchedulingConfigurer这个接口,设置taskScheduler
2、也可以配置文件配置,Spring Boot quartz 已经提供了一个配置用来配置线程池的大小 spring.task.scheduling.pool.size=10
3、配置线程池,再使用@Async开启异步任务

package com.nine.rivers.apps.core.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

import java.util.concurrent.ThreadPoolExecutor;

import static com.nine.rivers.apps.core.constants.NumberConstant.*;

/**
* 定时任务线程池配置解决多个定时任务阻塞问题
* 三种方法,任选期一:
* <p>1、重写SchedulingConfigurer#configureTasks(),直接实现SchedulingConfigurer这个接口,设置taskScheduler
* <p>2、也可以配置文件配置,Spring Boot quartz 已经提供了一个配置用来配置线程池的大小 spring.task.scheduling.pool.size=10
* <p>3、配置线程池,再使用@Async开启异步任务
*
* @author heck
* @date 2023/08/24
*/
@Configuration
public class ScheduleConfig implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskScheduler());
    }

    /**
     * 覆盖taskScheduler
     */
    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(SIX);
        taskScheduler.setThreadNamePrefix("ndp-apps-scheduler-pool-");
        return taskScheduler;
    }

}

方法三

    /**
     * 配置线程池,再使用@Async开启异步任务
     */
    @Bean
    public ThreadPoolTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor poolTaskExecutor = new ThreadPoolTaskExecutor();

        poolTaskExecutor.setCorePoolSize(FOUR);
        poolTaskExecutor.setMaxPoolSize(SIX);
        // 设置线程活跃时间(秒)
        poolTaskExecutor.setKeepAliveSeconds(TWO * SIX * TEN);
        // 设置队列容量
        poolTaskExecutor.setQueueCapacity(FOUR * TEN);

        poolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 等待所有任务结束后再关闭线程池
        poolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);

        return poolTaskExecutor;
    }


来源:Heck's Blog
地址:https://www.heckjj.com/post/654/
转载时须以链接形式注明作者和原始出处及本声明,否则将追究法律责任,谢谢配合!
阅读(725) | 评论(0) | 引用(0)