定时任务 Cron 表达式,了解一下?

959 阅读6分钟

一、概述

Cron表达式是一种广泛应用于Linux系统的时间表示格式,常用于定时任务的调度。Cron表达式可以通过指定不同的时间参数,描述一个在未来某个时间点执行的任务。

Spring框架也提供了相关支持基于@Scheduled注解,我们可以通过Cron表达式来使用重复性的定时任务。

二、Cron表达式语法

Cron表达式的语法如下:

秒 分 时 日 月 周几

其中每个字段都有其特定的含义。下面对每个字段进行详细介绍。

  1. 秒(0~59)秒的取值范围为0到59。表示每分钟的哪一秒钟执行任务。

  2. 分(0~59)分的取值范围为0到59。表示每小时的哪一分执行任务。

  3. 时(0~23)时的取值范围为0到23。表示每天的哪一小时执行任务。

  4. 日(1~31)日的取值范围为1到31,其中有些月份日数为30天或28天,所以当超出这些范围时,Cron表达式会自动处理。

  5. 月(1~12)月的取值范围为1到12。表示每年的哪一月执行任务。

  6. 周几(0~7,0和7都代表周日,1到6依次代表周一到周六)周几的取值范围为0到7。0和7都代表周日,1到6依次代表周一到周六。如果同时指定了日和周几,那么该任务会在满足两个条件时才执行。

除了数字之外,Cron表达式还可使用以下特殊字符:

  • *:表示匹配所有可能的值。
  • ?:只能用在日和周几字段中,表示不关心具体是哪一天或哪一个星期几,可以用于通配符。
  • -:表示区间,如在小时字段中使用10-12表示10点到12点。
  • ,:表示列表,如在周几字段中使用MON,WED,FRI表示周一、周三和周五。
  • /:表示递增,如在秒字段中使用3/15表示从第3秒开始每隔15秒执行一次。

还有一些常见的时间表达式,如:

  1. 每分钟执行一次 0 * * * * ? 表示每分钟的第0秒执行。

  2. 每小时执行一次 0 0 * * * ? 表示每小时的第0分0秒执行。

  3. 每天凌晨执行一次 0 0 0 * * ? 表示每天凌晨的0时0分0秒执行。

  4. 每周日凌晨执行一次 0 0 0 ? * SUN 表示每周日凌晨的0时0分0秒执行。

  5. 每月1号凌晨执行一次 0 0 0 1 * ? 表示每月1日凌晨的0时0分0秒执行。

  6. 每年1月1日凌晨执行一次 0 0 0 1 1 ? 表示每年1月1日凌晨的0时0分0秒执行。

  7. 每个整点执行一次 0 0 * * * ? 表示每个小时的第0分0秒执行,即每个整点执行一次。

  8. 每隔5秒执行一次 0/5 * * * * ? 表示每分钟内每隔5秒执行一次。

  9. 每隔10分钟执行一次 0 0/10 * * * ? 表示每小时内每隔10分钟执行一次。

  10. 每隔1小时30分钟执行一次 0 0/30 */1 * * ? 表示每隔1小时30分钟执行一次。

  11. 每天的固定时间执行 0 30 12 * * ? 表示每天的12时30分执行。

  12. 工作日的固定时间执行 0 30 16 ? * MON-FRI 表示周一至周五的16时30分执行。

  13. 每月的第一个周一执行 0 0 9 ? * 2#1 表示每月的第一个周一的9时0分0秒执行。

  14. 每月的最后一天执行 0 0 0 L * ? 表示每月的最后一天的0时0分0秒执行。

  15. 每隔3个月执行一次 0 0 0 1 */3 ? 表示每隔3个月的1日0时0分0秒执行。

  16. 每年的第二个月的第三个周五执行 0 0 0 ? 2 6#3 表示每年的第二个月的第三个周五的0时0分0秒执行。

  17. 每周六和周日的8点到10点之间每隔1分钟执行一次 0 */1 8-10 * * SAT,SUN 表示每周六和周日的8点到10点之间每隔1分钟执行一次。

  18. 每周一到周五的上午9点和下午4点各执行一次 0 0 9,16 ? * MON-FRI 表示每周一到周五的上午9点和下午4点各执行一次。

  19. 每天的上午8点到下午6点之间每隔半小时执行一次 0 0/30 8-18 * * ? 表示每天的上午8点到下午6点之间每隔半小时执行一次。

  20. 每年的12月31日23时59分59秒执行 59 59 23 31 12 ? 表示每年的12月31日23时59分59秒执行。

三、Spring框架的@Scheduled注解

Spring框架提供了@Scheduled注解,用于声明一个定时方法。我们可以通过在方法上添加@Scheduled注解,并指定Cron表达式,来实现定时任务的调度。下面是@Scheduled注解的语法:

@Scheduled(cron = "Cron表达式")

在SaleService类中定义一个方法,命名为calculateDailySales,并使用@Scheduled注解来声明该方法为定时任务:

@Service
public class SaleService {

    @Autowired
    private SaleDao saleDao;

    /**
     * 每天凌晨0点整计算前一天的销售数据
     */
    @Scheduled(cron = "0 0 0 * * ?")
    public void calculateDailySales() {
        // 计算前一天的开始和结束时间
        Date startDate = DateUtils.getStartDate(new Date());
        Date endDate = DateUtils.getEndDate(new Date());

        // 计算销售数据
        List<SaleData> saleDataList = calculateSaleData(startDate, endDate);

        // 将结果存储到数据库中
        saleDao.saveSales(saleDataList);
    }

    /**
     * 计算指定日期范围内的销售数据
     */
    private List<SaleData> calculateSaleData(Date startDate, Date endDate) {
        // ...
    }
}

在上述代码中,@Scheduled注解的Cron表达式为“0 0 0 * * ?”,表示每天凌晨0点整执行该任务。

四、总结

本文介绍了Cron表达式的语法和含义,并结合Spring @Scheduled注解给出了一个实际场景示例。通过该示例,我们可以熟悉如何使用Cron表达式来定义定时任务,并掌握Spring框架实现定时任务的基本方法。在使用定时任务时,需要注意任务的执行频率和耗时,以保证系统的性能和稳定性。

优点:

  1. Cron表达式可以高度灵活地指定任务的执行时间,支持许多常见的时间模式,并能够自定义时间精度。
  2. Cron表达式支持多个时间段、时间间隔、通配符等功能,可以满足各种复杂的时间调度需求。
  3. Cron表达式易于配置和维护,只需要简单的文本编辑器即可进行修改。
  4. 许多编程语言和操作系统都内置了对Cron表达式的支持,可以轻松地集成到其他系统中。

缺点:

  1. 由于Cron表达式的语法相对复杂,初学者可能需要一些时间来掌握其使用方法。
  2. Cron表达式不能处理任务执行时间的重叠问题,如果出现某个任务还未执行完就触发了下一个任务,那么就会导致混乱。
  3. 在运行大量定时任务的情况下,Cron表达式可能会导致系统负载过重,需要考虑合理的分布式处理方案。