1. 场景描述

场景是这样的两个定时任务分别是每天的4点和5点
@Scheduled(cron = “0 0 4 * * ?”)
@Scheduled(cron = “0 0 5 * * ?”)
4点的任务执行时间很长,一下子到8点
5点的任务为什么是等4点的结束才开始,不是5点直接开始

2. 问题原因

在Spring框架中使用@Scheduled注解定义定时任务时,默认情况下,每个任务都是在同一个线程中执行的。这意味着,如果一个任务的执行时间很长,它会阻塞后续任务的执行,直到当前任务完成。这就是为什么5点的任务会等待4点的任务结束才开始执行的原因。

3. 解决方案

为了确保定时任务能够按时执行,即使前一个任务还没有完成,您可以配置多个线程来执行定时任务。Spring允许您通过TaskScheduler来配置多个线程池,从而实现并发执行任务。

4. 配置多线程任务调度器

@Configuration
public class SchedulerConfig {

    @Bean
    public ThreadPoolTaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(10); // 设置线程池大小
        scheduler.setThreadNamePrefix("Scheduled-");
        scheduler.initialize();
        return scheduler;
    }
}

5. 注意事项

  • 线程安全:确保您的任务方法是线程安全的,因为多个任务可能会同时执行。
  • 任务冲突:如果多个任务访问共享资源,需要确保资源的同步或使用适当的并发控制机制。
  • 资源管理:合理配置线程池大小,以避免过多的线程消耗系统资源。
  • 错误处理:在任务方法中添加适当的错误处理逻辑,以便在任务执行失败时能够恢复或重试。

6. 代码测试demo

@Slf4j
@Component
public class TestSchedule {
    // 定义一个按照cron表达式定时执行的任务方法task1  每分钟执行1次
    @Scheduled(cron = "0 * * * * ?")
    public void task1() {
        try {
            // 打印任务开始的信息
            System.out.println("task1 start");
            // 模拟任务执行,休眠5秒
            TimeUnit.SECONDS.sleep(5);
            // 打印任务结束的信息
            System.out.println("task1 end");
        } catch (Exception e) {
            // 记录任务执行中的错误日志
            log.error("task1 error:", e);
        }
    }

    // 定义另一个按照相同cron表达式定时执行的任务方法task2  每分钟执行1次
    @Scheduled(cron = "0 * * * * ?")
    public void task2() {
        try {
            // 打印任务开始的信息
            System.out.println("task2 start");
            // 模拟任务执行,休眠5秒
            TimeUnit.SECONDS.sleep(5);
            // 打印任务结束的信息
            System.out.println("task2 end");
        } catch (Exception e) {
            // 记录任务执行中的错误日志
            log.error("task2 error:", e);
        }
    }
}

场景1: 不添加配置ThreadPoolTaskScheduler, 执行结果是tast2结束之后开始执行tast1, 顺序执行
在这里插入图片描述

场景2: 添加配置ThreadPoolTaskScheduler, 执行结果是tast1和tast1同时开始, 并发执行
在这里插入图片描述

7. 源码部分

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐