scheduled每5分钟执行一次_10分钟让你学会两种定时任务

本文介绍了定时任务的概念,并通过代码示例展示了如何使用Cron表达式实现每2秒执行一次的任务。Cron表达式包含6或7个域,每个域都有特定的含义和可选字符。此外,还简要提及了Quartz这个开源的Job调度库,它是如何与J2EE和J2SE结合使用的,并提供了创建和管理复杂定时任务的能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

何为定时任务

举个例子我有一个网站就叫他生活小助手吧,我的这个小助手有一个天气查询的功能,那么我的天气数据从何而来?实现方法一写一个爬虫程序去爬取中国气象台的天气信息,我觉得不大行。方法二使用第三方接口直接拿到返回结果做渲染。

0e50b93e33c96118a96737a721d0a9d0.png

99c2edb4e7f485c947f95abc07a33efc.png

但是像天气这种实时的数据肯定是要实时更新的,但是我们的程序对外提供的接口都是需要手动调用的,我的小助手网站难道需要我每个小时手动去调一次京东万象数据平台的接口吗?这当然是不现实的,所以我需要我的程序没过一个小时去自动执行方法去调用京东万象数据平台的接口拿到返回结果保存到类似于Redis这种非关系型数据库中。能够实现这个功能的角色就是接下来要讲到的定时任务。 Spring的Schedule

我先不介绍他的概念,直接上代码你可能都不用解释它是什么了f33598c683ae6b6ee5e909c0214d778e.png

一.引入依赖
<dependency>  <groupId>org.springframeworkgroupId>  <artifactId>spring-context-supportartifactId>dependency>
二.编写你想要被定时任务执行的方法
package com.jmy.schedule;import org.springframework.scheduling.annotation.Scheduled;import org.springframework.stereotype.Component;/*Scheduled 定时任务器 */public class ScheduledDemo {
    
        public void sayHello(){
    
            System.out.println("Hello! Scheduled!!!");    }}
三.将被执行方法所在类交由Spring的IOC容器管理
@Component // 看这里!!!!!!public class ScheduledDemo {
    
        public void sayHello(){
    
            System.out.println("Hello! Scheduled!!!");    }}
四.定时(任务什么时候被执行)
@Componentpublic class ScheduledDemo {
<think>我们要求配置一个定时任务,每天晚上10点(22点)开始,每5分钟执行一次。 在Spring的@Scheduled注解中,我们可以使用cron表达式来实现这个需求。 分析需求: 1. 每天晚上22点开始:即小时部分为22。 2. 每5分钟执行一次分钟部分使用0/5(从0分钟开始,每5分钟一次)。 3. 注意:在22点这个小时内的执行时间点为:22:00, 22:05, 22:10, ... , 22:55(因为每5分钟一次,共12次)。 然后从23点开始,同样每5分钟一次,直到23:55。但需求是每天晚上22点开始,并没有说结束时间,所以会一直执行到第二天的22点前?实际上,按照cron表达式,它会每天22点开始,然后每5分钟执行一次,直到第二天的21:59,然后到22点又开始新的一轮。 但是,这里有一个注意点:cron表达式中的“每天”是从0点到23:59。如果我们希望只在22点以后执行,那么我们需要在小时部分设置22-23(因为22点开始,到23:59)?但是这样设置的话,0点到21点就不会执行。然而,需求是“每天晚上10点开始”,并没有说白天不执行,所以这里有两种理解: a) 只在22点到23:59之间每5分钟执行一次,其他时间不执行。 b) 从22点开始,每5分钟执行一次,并且每天如此(即24小时每5分钟一次,但需求是22点开始,并没有说停止时间,所以默认是全天?) 显然,用户的需求是“每天晚上10点开始每5分钟执行一次”,这个描述通常意味着从22:00开始,到第二天早上某个时间结束?但是用户没有明确结束时间。然而,在定时任务中,如果要求从22点开始,然后一直持续每5分钟一次直到第二天22点前,那么实际上就是全天每5分钟一次,因为22点开始后,就会一直执行下去,包括第二天白天。 但是,用户可能的本意是:只在晚上22点以后的时间段内每5分钟执行一次,即22:00到23:55(因为23:55之后就是0点,而0点不属于晚上22点以后)。那么,我们需要将小时部分限制在22和23点。 因此,我们有两种配置方式: 1. 如果希望全天每5分钟执行一次(包括白天),那么cron表达式可以写成:`0 0/5 * * * ?`,但是这样会从0点就开始执行,不符合22点开始的要求。 2. 如果希望只在22点至23点之间每5分钟执行一次,那么小时部分设置为22-23:`0 0/5 22-23 * * ?` 但是,用户的需求是“每天晚上10点开始”,并没有说只到23点。通常,晚上10点开始,一般会持续到第二天早上?但是cron表达式的一天是以0点为分界的。所以,如果我们希望从22点开始执行,一直到第二天的21:59,然后从22点又开始,那么我们需要将小时部分设置为22,23,0-21(即22点到23点,以及0点到21点)。这样,整个小时部分就是除了21点到22点这一个小时之外的所有时间。但是这样写很复杂。 实际上,用户的需求可能是:在每天的22:00开始第一次执行,然后每5分钟执行一次,一直持续下去,包括第二天白天。也就是说,这个任务本来就是每5分钟执行一次,只是第一次执行是在22点。但是,cron表达式本身并不支持“从某个时间开始,然后周期性执行”这种概念。cron表达式定义的是每个时间点触发的时间规则。 因此,我们需要明确: - 如果用户希望全天每5分钟执行一次,那么可以直接用`0 0/5 * * * ?`,但是这样会在0点就开始执行,而不是22点。 - 如果用户希望只在22点以后(包括22点至23:59)执行,那么用`0 0/5 22-23 * * ?`,这样在22点至23点之间每5分钟执行一次,其他时间不执行。 - 如果用户希望从22点开始,然后一直持续到第二天,那么实际上就是全天执行,因为22点开始后,每5分钟一次,自然就会持续到第二天22点前,然后又从22点开始。所以,实际上就是全天执行。但是,第一次执行是在22点,那么如何保证第一次执行在22点呢?如果我们用`0 0/5 * * * ?`,那么第一次执行是在0点,而不是22点。 然而,在Spring的@Scheduled中,cron表达式是定义任务触发的时间点,而不是定义从何时开始周期执行。所以,如果我们配置为`0 0/5 * * * ?`,那么任务会在每天的0:00, 0:05, ... , 23:55执行。也就是说,在22点之前就已经执行了很多次。 所以,用户的需求可能是:在22:00第一次执行,然后每5分钟执行一次,直到第二天的21:55,然后等待22:00再次开始?这样,在22:00到21:55(第二天)这个周期内,每5分钟执行一次。但是,cron表达式无法直接表达“从22点开始到21:55结束”这样的周期,因为cron表达式是按天计算的。 因此,我们需要重新思考:用户可能希望的是,在22点之后(包括22点)到第二天22点之前,每5分钟执行一次。也就是说,全天24小时都执行,但是第一次执行是在22:00。但是,如果我们配置成每5分钟一次,那么0:00就会开始执行,所以不符合22点开始的要求。 那么,如何实现“从22点开始”呢?实际上,我们可以通过设置初始延迟(initialDelay)和固定速率(fixedRate)来实现,但是fixedRate是固定速率,它不会考虑具体的开始时间点(比如22点)。而且,fixedRate是从任务启动后就开始计时,所以很难控制到每天的22点开始。 因此,我们可能需要两个配置: 1. 在22:00启动一个任务,这个任务启动后,每5分钟执行一次。 2. 但是,这个任务在第二天22:00的时候,我们希望重新开始一个新的周期(即停止前一天的任务,启动新任务)?这样很复杂。 实际上,用户的需求可能只是希望在22点至第二天早上某个时间点执行?但用户没有明确结束时间。我们不妨与用户确认,但这里我们按照常见的理解:只在晚上22点至23:59之间执行,因为晚上10点开始,通常到0点就结束了(即当天晚上)。 所以,我们采用第二种方式:cron表达式设置为`0 0/5 22-23 * * ?`,表示在22点和23点这两个小时内,每5分钟执行一次。这样,从22:00开始,到23:55结束,共执行24次(每个小时12次)。 如果用户希望从22点开始,一直执行到第二天早上6点,那么小时部分需要写成22-23,0-6(注意:0-6表示0点到6点)。那么表达式为:`0 0/5 22-23,0-6 * * ?` 但是,用户没有明确结束时间,我们按照最小范围(即只到23:59)来配置。 因此,我们给出两种可能: 1. 只在22点和23点执行:`0 0/5 22-23 * * ?` 2. 如果用户希望执行到第二天早上6点:`0 0/5 22-23,0-6 * * ?` 由于用户问题中只说了“每天晚上10点开始每5分钟执行一次”,没有说结束时间,我们默认采用第一种(即当天22:00-23:59)。 所以,配置如下: ```java @Scheduled(cron = "0 0/5 22-23 * * ?") public void myTask() { // 任务内容 } ``` 但是,注意:cron表达式中的小时范围是0-23,我们这里用了22-23。另外,分钟部分0/5表示从0分钟开始,每5分钟一次。 另外,我们也可以使用zone属性指定时区,如果不指定,则使用服务器默认时区。 如果用户希望这个任务在22点开始,然后每5分钟一次,持续一整天(即24小时),那么实际上就是每5分钟执行一次,但是如何避免在22点之前执行呢?我们可以通过设置一个一次性任务在22点启动,然后启动一个固定速率的任务(每5分钟执行一次)。但是这样就需要动态配置任务,比较复杂。通常,如果要求全天执行,那么就不需要特别指定开始时间,因为全天执行自然包括22点。所以,如果用户确实需要全天执行,那么建议使用`0 0/5 * * * ?`,并忽略22点之前执行的部分。 但是,用户明确要求“每天晚上10点开始”,所以可能并不希望22点之前执行。因此,我们采用第一种方式(只在22点和23点执行)更符合字面意思。 结论:使用`0 0/5 22-23 * * ?` 验证: 执行时间点:22:00, 22:05, 22:10, 22:15, 22:20, 22:25, 22:30, 22:35, 22:40, 22:45, 22:50, 22:55, 23:00, 23:05, ... , 23:55. 这样,从22:00开始,每5分钟一次,直到23:55结束。 如果用户需要更长时间段,可以调整小时部分。 因此
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值