• @Scheduled同时执行多个定时任务所导致的并发问题


    @Scheduled的执行顺序
    @Scheduled注解会在默认情况下以单线程的方式执行定时任务。
    这个“单线程”指两个方面:

    如果一个定时任务执行时间大于其任务间隔时间,那么下一次将会等待上一次执行结束后再继续执行。
    如果多个定时任务在同一时刻执行,任务会依次执行。
    那么这种效果肯定不是我们想要的,为了使@Scheduled效率更高,我们可以通过两种方法将定时任务变成多线程执行:

    1、在启动类中配置TaskScheduler线程池大小

    @Bean
    public TaskScheduler taskScheduler() {
    ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
    taskScheduler.setPoolSize(50);
    return taskScheduler;
    }
     
    2、利用Spring提供的@Async注解和@EnableAsync注解

    @Component
    @EnableAsync
    public class TimedTask{
    @Async
    @Scheduled(cron = "0 0/1 * * * ?")//每一分钟执行一次
    public void taskA() {
    //执行你的业务逻辑
    }

    @Async
    @Scheduled(cron = "0 0/1 * * * ?")//每一分钟执行一次
    public void taskB() {
    //执行你的业务逻辑
    }
     
    通过以上方式,定时任务将会以多线程的方式开始执行,减小了程序耦合度,提升运行效率。

    @Scheduled同步
    定时任务在同一时刻开始执行有两种情况:

    多个任务的间隔时间相同,如都是1分钟执行一次,那么每一分钟,这些任务都会一起执行。
    多个任务的间隔时间不同,但有重合的时刻。如一个任务每天零点执行,另一个任务每一分钟执行,那么这两个任务在零点的时刻会一起执行。
    由于任务都是异步的,如果多个任务同时操作同一资源,那么必然会导致错误。
    这个时候可以给任务加锁,保证任务互不干扰,拥有在同一时刻执行的线程安全:

    @Component
    @EnableAsync
    public class TimedTask{

    private Object lock = new Object();

    @Async
    @Scheduled(cron = "0 0 0 * * ?")//每天零点执行
    public void taskA() {
    synchronized(lock){
    //执行你的业务逻辑
    }
    }

    @Async
    @Scheduled(cron = "0 0/1 * * * ?")//每一分钟执行一次
    public void taskB() {
    synchronized(lock){
    //执行你的业务逻辑
    }
    }
     
    控制定时任务的执行顺序
    如果对执行顺序有要求的定时任务,有如下两种情况:
    1、在某一时刻同时执行
    如任务A在零点初始化数据,任务B每分钟更新数据。那么在零点,必须是任务A先执行,其次才是B。但加锁只能保证线程安全,不能保证执行顺序。在这种情况下,我们可以借助redis设置获取锁的顺序,亦或标志字进行执行顺序的判断。
    2、总是同时执行
    在任务间隔相同的情况下,一般为业务的解耦,不应操作共享资源,应当放至同一个定时任务中执行。

    创作不易,留下你的小赞,暖我一整天~


    ————————————————
    版权声明:本文为CSDN博主「MaYuKang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/MaYuKang/article/details/121839279

  • 相关阅读:
    kolla-ansible安装openstack(Ocata)
    OpenStack 虚机网卡的创建过程
    C语言 IPv6 十六进制 转 十进制
    python IPv6 十进制和十六进制互转
    ICMPv6 Packet Types and Codes
    scapy IPv6 NS NA报文构造
    最接近的数 牛客网 程序员面试金典 C++ Python
    最近公共祖先 牛客网 程序员面试金典 C++ Python
    有向路径检查 牛客网 程序员面试金典 C++ Python
    检查是否是BST 牛客网 程序员面试金典 C++ java Python
  • 原文地址:https://www.cnblogs.com/javalinux/p/16363923.html
Copyright © 2020-2023  润新知