• 定时任务


    1、定时任务

    1)cron表达式

    语法:

    秒 分 时 日 月 周(周几) 年(Spring不支持年,支持前6位)


    特殊字符

    ① , :枚举

    7,9,23 * * * * ? 任意时刻的7,9,23秒启动该任务

    ② - :范围

    7-20 * * * * ? 任意时刻的7-20秒,每秒启动一次

    ③ * :任意 指定位置的任意时刻

    ④ / :步长

    7/5 * * * * ? 任意时刻的第七秒启动,每5秒执行一次

    */5 * * * * ? 任意秒启动,每5秒执行一次

    ⑤ ?:

    (出现在日和周几的位置):为了防止日和周冲突,在周和日上如果要写通配符?

    ⑥ L:(出现在日和周的位置)

    last:最后一个 (cron="* * * ? * 3L"):每月的最后一个周二

    ⑦ W:

    Work Day:工作日 (cron="* * * W * ?"):每个月的工作日触发

    (cron="* * * LW * ?"):每个月的最后一个工作日触发

    ⑧ #:第几个

    (cron="* * * ? * 5#2"):每个月的第 2 个周 4


    2)SpringBoot整合corn表达式做定时任务

    /*
     * 定时任务
     * 1、@EnableScheduling 开启定时任务功能
     * 2、@Scheduled 开启定时任务
     * 3、自动配置类: TaskSchedulingAutoConfiguration
     *
     * 异步任务
     *   1、@EnableAsync: 开启异步任务
     *   2、在方法上标注 @Async
     *   3、自动配置类: TaskExecutionAutoConfiguration
     *         属性默认绑定: TaskExecutionProperties
     */
    @Slf4j
    @EnableAsync
    @EnableScheduling
    @Component
    public class HelloSchedule {
    
        /*
        * 1、cron表达式不支持第7位的年
        * 2、周: 1-7 代表周一到周日
        * 3、定时任务不应该阻塞。默认是阻塞的
        *       1)让业务以异步的方式自己提交到线程池
        *       CompletableFuture.runAsync(()->{
        *            xxxxService.hello();
        *        }, executor);
    
                2)支持定时任务线程池
                设置 TaskSchedulingProperties(定时任务配置绑定类)
                spring.task.scheduling.pool.size: xxx  => 有些版本不一定好使
    
    
                3)直接让定时任务异步执行
                @EnableAsync + @Async
    
                使用异步 + 定时任务来完成定时任务不阻塞的功能
    
    
        * */
        @Scheduled(cron = "* * * * * ?")
        public void hello() throws InterruptedException {
            log.info("hello。。。");
            Thread.sleep(3000);
        }
    }


    3)、定时任务-分布式系统下的问题

    当同个服务启动多个时:

    ①、需要使用分布式锁,来保证只有一个服务来执行定时任务。

    ②、同时需要保证定时任务执行的幂等性

    image-20220326092719153


    @Service
    public class SeckillSkuScheduled {
    
        @Autowired
        SeckillService seckillService;
    
        @Autowired
        RedissonClient redissonClient;
    
        private final String upload_lock = "seckill:upload:lock";
    
        //todo 幂等性问题 -> 同一件秒杀商品不应该上架两次
        @Scheduled(cron = "0 * * * * ?")
        public void uploadSeckillSkuLatest3Days(){
            //重复上架无需处理
            System.out.println("秒杀商品上架...");
            //加上分布式锁,保证只有一个定时任务执行
            RLock lock = redissonClient.getLock(upload_lock);
            lock.lock(10, TimeUnit.SECONDS); //十秒中没有执行完,自动释放锁,不会造成死锁
            try {
                seckillService.uploadSeckillSkuLatest3Days();
            } finally {
                lock.unlock();
            }
        }
    }
  • 相关阅读:
    写作 —— 细节与画面感
    写作 —— 细节与画面感
    诸子经典 —— 《管子》
    诸子经典 —— 《管子》
    金庸小说的模式
    金庸小说的模式
    SQLite中如何用api操作BLOB类型的字段
    Android WebView挂马漏洞--各大厂商纷纷落马
    [置顶] android开发之来电自动拒接并自动回复短信_上课模式app
    步步为营Hibernate全攻略(四)剪不断理还乱之:复合主键 && 组合映射
  • 原文地址:https://www.cnblogs.com/houchen/p/16066582.html
Copyright © 2020-2023  润新知