首页 > 其他 > 详细

@Scheduled阻塞导致未执行生效的情况分析

时间:2021-06-16 16:40:20      阅读:32      评论:0      收藏:0      [点我收藏+]

@Scheduled阻塞导致未执行生效的情况分析

今天排查线上数据,发现数据并未更新,查看日志发现更新数据的定时任务并没有执行,而执行该定时任务的时间发现执行了另外的定时任务,所以因此初步判断可能是定时任务阻塞导致相同时间的定时任务有未执行任务。

写了个DEMO果真复现了,@Scheduled注解的定时任务为单线程执行,所以必定会有阻塞情况。

测试代码

  • 定时任务【1】DEMO代码
@Component
public class Test01 {
    // 每秒执行一次
    @Scheduled(cron = "0/1 * * * * ? ")
    public void test() {
        // 时分秒
        String nowTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"));
        // 日志打印
        System.out.println(nowTime + "   任务【1】执行  线程:" + Thread.currentThread().getName());
    }
}
  • 定时任务【2】DEMO代码
@Component
public class Test02 {
    // 每5秒执行一次
    @Scheduled(cron = "0/5 * * * * ? ")
    public void test() {
        String nowTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"));
        System.out.println(nowTime + "   任务【2】执行  线程:" + Thread.currentThread().getName());
        try {
            // 模拟耗时任务,阻塞2s
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

服务启动后运行结果

技术分享图片

原因分析

  • 由程序运行后的打印结果可以发现两个任务均是使用的同一线程。
  • 任务【1】应该是每秒执行一次的,但是执行时间上可以发现,任务【1】的执行时间不是连续的,这就说明有时间点是任务【1】没有执行的,而这些时间点恰好任务【2】正在执行中,单线程的原因线程此时阻塞,从而导致这些时间点任务【1】没有执行。

解决方案

  • 添加@Async注解或者使用自定义线程池执行任务

代码这里就不贴了,就是在上面的任务【1】和任务【2】的@Scheduled注解上面添加一个注解@Async即可。

多线程执行定时任务后的执行结果

技术分享图片
很明显,任务【1】每秒执行的时间连续了!!!没有未执行的情况。
但需要注意的是,可以对@Async进行自定义配置,使其使用时,内部也是通过创建ThreadPoolExecutor线程池来执行。

@Scheduled阻塞导致未执行生效的情况分析

原文:https://www.cnblogs.com/qukun/p/14889676.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!