admin 管理员组

文章数量: 1184232

 1.启动类添加注解启动定时任务相关注解的识别:

@EnableScheduling
@SpringBootApplication
public class Application {

 

2.添加定时任务配置


/**
 * @Description: @schedule 注解 是springboot 常用的定时任务注解,使用起来简单方便,
 * 但是如果定时任务非常多,或者有的任务很耗时,会影响到其他定时任务的执行,因为schedule 默认是单线程的,
 * 一个任务在执行时,其他任务是不能执行的.解决办法是重新配置schedule,
 * 改为多线程执行.只需要增加下面的配置类就可以了.
 *
 * @Scheduled注解这种方式实现的定时任务默认是单线程执行的。
 * 所以如果你在一个定时任务A中使用了阻塞的方法,这个时候另一个定时任务B执行时间到了,
 * 定时任务B也不会执行。
 * @param: null
 * @return 
 * @date 2021/8/3 14:17
*/
@Configuration
public class ScheduleConfig implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        Method[] methods = BatchProperties.Job.class.getMethods();
        int defaultPoolSize = 6;
        int corePoolSize = 0;
        if (methods != null && methods.length > 0) {
            for (Method method : methods) {
                Scheduled annotation = method.getAnnotation(Scheduled.class);
                if (annotation != null) {
                    corePoolSize++;
                }
            }
            if (defaultPoolSize > corePoolSize)
                corePoolSize = defaultPoolSize;
        }
        taskRegistrar.setScheduler(Executors.newScheduledThreadPool(corePoolSize));
    }
}

 2.1如果业务场景需要可以添加线程池配置

/**
 * @description: 项目中有需要监听文件、文件夹的需求,以便在文件、文件夹发生变化时出发相应的业务流程。这里使用Spring Boot + Apache Commons IO方案。
 * 另外,Apache Commons IO涉及到多线程的应用,项目中应指定线程池的相关配置
 * @author:  
 * @create: 2021-10-20 16:06
 */
@Configuration
@EnableAsync
@Slf4j
public class AsyncConfig implements AsyncConfigurer {
    @Bean
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 设置线程池核心容量
        executor.setCorePoolSize(20);
        // 设置线程池最大容量
        executor.setMaxPoolSize(30);
        // 设置任务队列长度
        executor.setQueueCapacity(200);
        // 设置线程超时时间
        executor.setKeepAliveSeconds(60);
        // 设置线程名称前缀
        executor.setThreadNamePrefix("AnalysisWebThread-");
        // 设置任务丢弃后的处理策略
//        AbortPolicy:直接抛出异常,这是默认策略;
//        CallerRunsPolicy:用调用者所在的线程来执行任务;
//        DiscardOldestPolicy:丢弃阻塞队列中靠最前的任务,并执行当前任务;
//        DiscardPolicy:直接丢弃任务;
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new CustomAsyncExceptionHandler();
    }

    /*
     * 处理异步方法中未捕获的异常  
     */
    class CustomAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {

        @Override
        public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
            log.info("### Exception message - {}", throwable.getMessage());
            log.info("### Method name - {}", method.getName());
            log.info("### Parameter values - {}", Arrays.toString(obj));
            if (throwable instanceof Exception) {
                Exception exception = (Exception) throwable;
                log.info("### exception:{}", exception.getMessage());
            }
            throwable.printStackTrace();
        }
    }
}

 

 3.添加对应业务场景需要的定时任务


@Slf4j
@Component
public class MyTask {

    /**
     * @Description: 当方法的执行时间超过任务调度频率时,调度器会在下个周期执行;
     * 假设work()方法在第0秒开始执行,每10秒执行一次,当前方法执行了12秒,那么下一次执行work()方法的时间是第20秒。
     * @author 
     * @date 2022/4/6 10:33
    */
    @Scheduled(cron = "0/10 * * * * *")
    public void work() {
        // task execution logic
    }

    /**
     * @Description: 固定间隔任务:下一次的任务执行时间,是从方法最后一次任务执行结束时间开始计算。并以此规则开始周期性的执行任务。
     * 假设work()方法每隔10秒执行一次,在第0秒开始执行,方法执行了12秒,那么下一次执行work()方法的时间是第22秒
     * @author 
     * @date 2022/4/6 10:33
     */
    @Scheduled(fixedDelay = 1000*10)
    public void workFixedDelay() {
        // task execution logic
    }

    /**
     * @Description: 固定频率任务:按照指定频率执行任务,并以此规则开始周期性的执行调度.
     * 注意:当方法的执行时间超过任务调度频率时,调度器会在当前方法执行完成后立即执行下次任务.
     * 假设work()方法每10秒执行一次,在第0秒开始执行,方法执行了12秒,那么下一次执行work()方法的时间是第12秒.
     * @author 
     * @date 2022/4/6 10:33
     */
    @Scheduled(fixedRate = 1000*10)
    public void workFixedRate() {
        // task execution logic
    }

本文标签: 详细 SpringBoot schedule