25Quartz定时任务学习笔记

                       Quartz定时任务学习笔记

1 quartz概念

quartz就是基于Java实现的任务调度框架,用于执行你想要执行的任何任务。

定时任务,定时的执行任务。

2 quartz运行环境

1.quartz可以在应用程序服务器内被实例化,并且参与事务

2.quartz可以运行嵌入在另一个独立式应用程序

3 quartz设计模式

1.Builder模式

2.Factory模式

3.组件模式(任务组件job,触发器组件trigger,调度组件scheduler)

4.链式编程

4 quartz学习的核心概念

3个组件:

任务job:Job就是你想要实现的任务类,每一个Job必须实现org.quartz.job接口,且只需实现接口定义的execute()方法

触发器trigger:trigger为你执行任务的触发器,比如你想每天定时3点发送一份统计邮件,

​ Trigger将会设置3点进行执行该任务Trigger主要包含SimpleTrigger和CronTrigger两种。

调度scheduler:scheduler为任务的调度器,它会将任务job及触发器Trigger整合起来,负责基于Trigger设定的时间来执行Job.

5 quartz的体系结构

quartz体系结构

6 quartz的几个常用API

scheduler 思该丢的

job 工作任务

JobDetail 实例

JobDataMap 数据对象

Trigger 触发器

TriggerBuilder 触发器创建器

JobBuilder 声明一个任务实例

JobListener,TriggerListener,SchedulerListener 监听器, 用于对组件的监听

7 quartz的使用

7.1 准备工作

7.2 引入quartz包

<!--quartz核心包-->
    <dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz</artifactId>
        <version>2.3.0</version>
    </dependency>
    <!--工具-->
    <dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz-jobs</artifactId>
        <version>2.3.0</version>
    </dependency>
</dependencies>

7.3 入门案例

7.4 Job和JobDetail介绍

Job:工作任务的接口,任务类需要实现execute方法,类似于JDK的timeTask的run方法
在里面编写任务执行的业务逻辑

Job实例在quartz中的生命周期,每次调度器执行job时,它在调用extcute方法前会创建一个新的job实例,

​ 当调度完成后,关联的job对象实例会被释放,释放的实例会被垃圾回收机制回收;

JobDetail:JobDetail为Job实例提供了许多设置属性,以及JobDataMap成员变量属性,它用来存储特定job
实例的状态信息,调度器需要借助JobDetail对象来添加Job实例。

JobDetail重要属性:name、group、jobClass、jobDataMap
jobDetail.getKey().getName(); //job名称
jobDetail.getKey().getGroup(); //job组名
jobDetail.getJobClass().getName(); //job任务类

7.5 JobExecutionContext介绍

。当scheduler调用一个job,就会将hjobExecutionContext传递给Job的execute()方法;

。Job能通过jobExecutionContext对象访问到quartz运行时候的环境以及job本身的明细数据;

7.6 JobDataMap介绍

1.使用Map获取

​ 在进行任务调度时,jobDataMap存储在JobExecutionContext中,非常方便获取;

7.7 有状态的Job和无状态的Job

@PersistJobDataAfterExecution注解的使用

有状态的job可以理解为多次job调用期间可以持有一些状态信息,这些状态信息存储在JobDataMap中,
而默认的无状态job每次调用时都会创建一个新的jobDataMap.

1.修改HelloSchedulerDemo.java,添加usingJobData(“count”,0),表示计数器

JobDetail job = JobBuilder.newJob(HelloJob.class)
				          .withIdentily("job1","group1") //定义该实例唯一标识
						  .usingJobData("message","打印日志")
						  .usingJobData("count",0)
						  .build();

2.修改HelloJob.java

添加countd setting和getting方法

private int count;
public void setCount(int count){
	this.count = count;
}

HelloJob类没有添加@PersistJobDataAfterExecution注解,每次调用时都会创建一个新的jobDataMap,不会累加;
HelloJob类添加@PersistJobDataAfterExecution注解,多次job调用期间可以持有一些状态信息,即可以实现count的累加。

7.8 Trigger介绍

触发器

7.9 SimpleTrigger触发器

simpleTrigger对于设置和使用是最为简单的一种quertzTrigger;
它是为那种需要在特定的日期/时间启动,且以一个可能的间隔时间重复执行n次的job所设计的,

案例一:表示在一个指定的时间段内,执行一次作业任务;
案例二:在指定的时间间隔内多次执行作业任务
案例三:指定任务结束时间

需要注意的要点:
。SimpleTrigger的属性有:开始时间、结束时间、重复次数和重复的时间间隔
。重复次数属性的值可以为0、正整数、或常量SimpleTrigger.REPEAT_INDEFINITELY
。重复的时间间隔属性值必须为0、或长整型的正整数,以毫秒作为时间单位,当重复的时间间隔为0时,
意味着与Trigger同时出发执行。
。如果有指定结束时间属性值,则结束时间属性值优先于重复次数属性,这样的好处在于:
当我们需要创建一个每间隔10秒钟触发一次直到指定的结束时间的Trigger,而无需去计算
从开始到结束所重复的次数,我们只需简单的指定结束时间和REPEAT_INDEFINITELY作为重复次数的属性值即可。

7.10 CronTrigger触发器

​ 如果你需要像日历那样按日程来触发任务,而不是像SimpleTrigger那样每隔特定的间隔时间触发,
CronTrigger通常比SimpleTrigger更有用,因为它是基于日历的作业调度器。

使用CronTrigger,你可以指定比如"每个周五中午",或者"每个工作日9:30"或者从每个周一、周三、周五的上午9:00
到上午10:00之间每隔五分钟"这样日程安排来触发。甚至,像SimpleTrigger一样,CronTrigger也有一个startTime
以指定日程什么时候开始,也有一个(可选)endTime以指定何时日程不再继续。

1.cron Expression----cron表达式

cron表达式被用来配置cronTrigger实例,cron表达式是一个由7个子表达式组成的字符串,每个子表达式都描述了
一个单独的日程细节。这些子表达式用空格分隔,分别表示:

表示式 = 秒 分 时 日 月 周
1.seconds 秒
2.minutes 分s
3.hours 小时
4.day-of-month 月中的天 =日
5.month 月
6.day-of-week 周中的天 =周几
7.year 年(可选)

  取值:
    字段       运行值            特殊字符
    秒         0-59              , - * /0-59              , - * /
    小时       0-23              , - * /1-31              , - * / ?1-12              , - * /1-7 sun-sat       , - * / ?
    年        不填写             , - * /			 
    ,      指定多个值 MON,WED,FRI 周一、周三、周五
	 -      表示区间  10-12 表示10,11,12都会触发
	 *      "每个"   日中的*表示一个月的每一天都会触发
	 ?      在日和周中使用互斥  不设置这个字段的值  比如每月15日  不能保证都是周二,所有周就应该?
	 /      表示增量 分中的0/15  每隔15分钟触发一次		
     
     练习:
     "0 0     10,14,16  *  *  ?"       ---每天的101416点触发
     "0 0/30  9-17      *  *  ?"       ---朝九晚五时间内每半小时,从0分钟开始每隔30分钟触发一次
     "0 0     12        ? *  WED"      ---每周三12点触发
     "0 0     12        ? *  *    ?"  ---每天12点触发
     "0 15    10        ? *  *"        ---每天上午1015分触发
     "0 15    10        *  *  ?"       ---每天1015分触发
     "0 15    10        *  *  ?   *"   ---每天1015分触发
     "0 15    10        *  *  ?  2005" ---2005年的每天10:15分触发
     "0 0-5   14        *  *  ?"       ---每天下午2点到2:05期间的每1分钟触发
     "0 10,44 14        *  ?  3    WED" ---每年2月的210分和2:44触发
     "0 15    10        ?  *  MON-FRI"  ---周一到周五的10:15分触发
     "0 15    10       15  *  ?"        ---每月1510:15分触发

7.11 配置SchedulerFactory

quartz以模块方式架构,因此,要使它运行,几个组件必须很好的咬合在一起。幸运的是,
已经有了一些现存的助手可以完成这些工作。
所有的scheduler实例都是由schedulerFactory创建。
quartz的三个核心概念:调度器,任务,触发器

大家都知道,一个作业,比较重要的三个要素就是scheduler,jobDetail,trigger;
而Trigger对于job而言就好比一个驱动器,没有触发器来定时驱动作业,作业就无法运行,
对于job而言,一个job可以对应多个trigger,但对于trigger而言,一个trigger只能对应一个job,
所以,一个trigger只能指派给一个job,如果你需要一个更复杂的触发计划,你可以创建多个
trigger并指派给同一个job。

quartz的创建方式:
(1)stdchedulerFactory:
quartz默认的schedulerFactory
。使用一组参数(java.util.properties)来创建和初始化quartz调度器
。配置参数一般存储在quartz.properties文件中
。调用getScheduler方法就就能创建和初始化调度器对象
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();

启动任务调度:
scheduler.start();
任务调度挂起,暂停操作:
scheduler.standby();
关闭调度任务:关闭后不能重新启动
scheduler.shutdown();

7.12 quartz.properties

我们也可以在项目的资源目下添加quartz.properties文件,去覆盖底层的配置文件
组成部分:
。调度器属性
org.quartz.scheduler.instanceName
。线程池属性
threadCount最好不要超过100

通过Properties设置工厂属性的缺点在于硬代码,假如需要修改例子中的线程数量,
将不得不修改代码,然后重新编译。我们这里不推荐使用。

8 quartz监听器

8.1 概念

quartz的监听器用于当任务调度中你所关注的事件发生时,能够及时获取这一事件的通知。
类似于任务执行过程中的邮件,短信类的提醒。quartz监听器主要有jobListener,triggerListener,
schedulerListener三种。顾名思义,分别表示任务,触发器,调度器对应的监听器。三者的使用方法类似,
在开始接受监听器之前,需要明确两个概念:全局监听器和局部监听器,二者的区别在于:

全局监听器能够接受到所有的job/trigger的事件通知;
而局部监听器只能接收到在上面注册的job或trigger的事件,不在其上面注册的job或trigger则不会进行监听。

8.2 JobListener任务的监听

任务调度过程中,与任务相关的事件包括:job开始要执行的提示;job执行完成的提示灯

添加到全局监听器:

scheduler.getListenerManager().addJobListener(new MyJobListener(),EverythingMatcher.allJObs));

添加到局部监听器 只有任务为job1时,MyJobListener监听器才会执行

scheduler.getListenerManager().addJobListener(new                     
                                           MyJobListener(),KeyMatcher.keyEquals(JobKey.jobKey("job1","group1"))));

8.3 TriggerListener触发器的监听

创建并注册一个全局的trigger listener

scheduler.getListenerManager().addTriggerListener(new MyTriggerListener(),EverythingMatcher.allTriggers);

创建并注册一个局部的trigger listener

scheduler.getListenerManager().addTriggerListener(
                     new MyTriggerListener(),KeyMatcher.keyEquals(TriggerKey.triggerKey("trigger1","group1")));

8.4 SchedulerListener调度器的监听

创建调度器的监听:

scheduler.getListenerManager().addSchedulerListener(new MySchedulerListener());

移除对应的调度器的监听:

scheduler.getListenerManager().removeSchedulerListener(new MySchedulerListener());

9 代码演示

9.1 quartz代码

9.1.1 HelloJob.java

Job类

package com.tangguanlin.quartz;
import org.quartz.*;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
 * 说明:
 * 作者:汤观林
 * 日期:2021年06月13日 18时
 */
@PersistJobDataAfterExecution //多次调用job的时候,会对job进行持久化,保存一个数据的信息
public class HelloJob implements Job {

    private int count;

    public void setCount(int count) {
        this.count = count;
    }

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

        //输出当前时间
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateStr = sdf.format(date);
        //获取JobDetail的内容
        JobKey jobKey = jobExecutionContext.getJobDetail().getKey();
        System.out.println("工作任务名称"+jobKey.getName()+":工作任务的组"+jobKey.getGroup());
        System.out.println("任务类的名称"+jobExecutionContext.getJobDetail().getJobClass().getName());

        //从JobDetail对象中获取jobDataMap的数据
        JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
        String jobDetailMessage = jobDataMap.getString("message");
        System.out.println("任务数据的参数值:"+jobDetailMessage);

        //从Trigger对象中获取jobDataMap的数据
        JobDataMap jobDataMap1 = jobExecutionContext.getTrigger().getJobDataMap();
        String triggerMessage = jobDataMap1.getString("message");
        System.out.println("触发器数据的参数值:"+triggerMessage);

        //获取Trigger的内容
        TriggerKey triggerKey = jobExecutionContext.getTrigger().getKey();
        System.out.println("触发器名称"+triggerKey.getName()+":触发器的组"+triggerKey.getGroup());

        //获取其他的内容
        System.out.println("当前任务的执行时间:"+jobExecutionContext.getFireTime());
        System.out.println("下一次任务的执行时间:"+jobExecutionContext.getNextFireTime());

        //工作内容
        System.out.println("正在进行数据库的备份工作,备份数据库的时间是:"+ dateStr);

        ++count;
        System.out.println("count的数量:"+count);
        //将count存放到jobDataMap中
        jobExecutionContext.getJobDetail().getJobDataMap().put("count",count);
    }
}

9.1.2 HelloSchedulerDemo.java

调度类

package com.tangguanlin.quartz;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
/**
 * 说明:
 * 作者:汤观林
 * 日期:2021年06月13日 18时
 */
public class HelloSchedulerDemo {

    public static void main(String[] args) throws SchedulerException {

        //1.调度器(scheduler)从工厂中获取调度实例
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

        //2.任务实例(JobDetail)
        //加载任务类,与HelloJob完成绑定
        JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
                .withIdentity("job1", "group1") //参数1:任务名称(唯一性) 参数2:任务组的名称
                .usingJobData("message","打印日志")
                .usingJobData("count",0)
                .build();

        //3.触发器(Trigger)
        SimpleTrigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger1", "group1") //参数1:触发器的名称(唯一性) 参数2:触发器组的名称
                .usingJobData("message","simple触发器")  //传递参数,名称message
                .startNow() //马上启动触发器
                .withSchedule(SimpleScheduleBuilder.simpleSchedule().repeatSecondlyForever(5)) //每5秒执行一次
                .build();

        //4.让调度器关联任务和触发器,保证按照触发器定义的条件执行任务
        scheduler.scheduleJob(jobDetail,trigger);

        //5.启动调度器
        scheduler.start();
    }
}

9.2 quartz Trigger代码

9.2.1 HelloJobTrigger.java

Job类

package com.tangguanlin.quartz;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Trigger;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
 * 说明:
 * 作者:汤观林
 * 日期:2021年06月14日 02时
 */
public class HelloJobTrigger implements Job{

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

        //输出当前时间
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateStr = sdf.format(date);

        //工作内容
        System.out.println("正在进行数据库的备份工作,备份数据库的时间是:"+ dateStr);

        Trigger trigger = jobExecutionContext.getTrigger();
        System.out.println("jobkey的名称"+trigger.getJobKey().getName()+" jobkey的组名称:"+trigger.getJobKey().getGroup());

        System.out.println("任务的开始时间:"+trigger.getStartTime() +"  任务的结束时间:"+trigger.getEndTime());

    }
}

9.2.2 HelloSchedulerDemoTrigger.java

调度类

package com.tangguanlin.quartz;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.util.Date;
/**
 * 说明:
 * 作者:汤观林
 * 日期:2021年06月13日 18时
 */
public class HelloSchedulerDemoTrigger {

    public static void main(String[] args) throws SchedulerException {

        //1.调度器(scheduler)从工厂中获取调度实例
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

        //设置任务的开始时间
        Date startDate = new Date();
        //任务的爱是时间推迟3s
        startDate.setTime(startDate.getTime()+3000);

        //设置任务的结束时间
        Date endDate = new Date();
        //任务的结束时间推迟10秒(10秒后停止)
        endDate.setTime(endDate.getTime()+10000);

        //2.任务实例(JobDetail)
        //加载任务类,与HelloJob完成绑定
        JobDetail jobDetail = JobBuilder.newJob(HelloJobTrigger.class)
                .withIdentity("job1", "group1") //参数1:任务名称(唯一性) 参数2:任务组的名称
                .build();

        //3.触发器(Trigger) .withSchedule(SimpleScheduleBuilder.simpleSchedule().repeatSecondlyForever(5)) //每5秒执行一次
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger1", "group1") //参数1:触发器的名称(唯一性) 参数2:触发器组的名称
                //.startNow() //马上启动触发器
                .withSchedule(SimpleScheduleBuilder.simpleSchedule().repeatSecondlyForever(5)) //5秒后重复执行
                .startAt(startDate) //设置任务的开始时间
                .endAt(endDate)  //设置任务的结束时间
                .build();

        //4.让调度器关联任务和触发器,保证按照触发器定义的条件执行任务
        scheduler.scheduleJob(jobDetail,trigger);

        //5.启动调度器
        scheduler.start();
    }
}

9.3 quartz SimpleTrigger代码

9.3.1 HelloJobSimpleTrigger.java

Job类

package com.tangguanlin.quartz;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 说明:
 * 作者:汤观林
 * 日期:2021年06月14日 02时
 */
public class HelloJobSimpleTrigger implements Job{

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

        //输出当前时间
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateStr = sdf.format(date);

        //工作内容
        System.out.println("正在进行数据库的备份工作,备份数据库的时间是:"+ dateStr);
    }
}

9.3.2 HelloSchedulerDemoSimpleTrigger.java

调度类

package com.tangguanlin.quartz;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.util.Date;
/**
 * 说明:
 * 作者:汤观林
 * 日期:2021年06月13日 18时
 */
public class HelloSchedulerDemoSimpleTrigger {

    public static void main(String[] args) throws SchedulerException {

        //1.调度器(scheduler)从工厂中获取调度实例
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

        //设置任务的开始时间
        Date startDate = new Date();
        //任务的开始时间推迟3s
        startDate.setTime(startDate.getTime()+3000);

        //设置任务的结束时间
        Date endDate = new Date();
        //任务的结束时间推迟10秒
        endDate.setTime(endDate.getTime()+10000);

        //2.任务实例(JobDetail)
        //加载任务类,与HelloJob完成绑定
        JobDetail jobDetail = JobBuilder.newJob(HelloJobSimpleTrigger.class)
                .withIdentity("job1", "group1") //参数1:任务名称(唯一性) 参数2:任务组的名称
                .build();

        //3.触发器(Trigger) .withSchedule(SimpleScheduleBuilder.simpleSchedule().repeatSecondlyForever(5)) //每5秒执行一次
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger1", "group1") //参数1:触发器的名称(唯一性) 参数2:触发器组的名称
                //.startNow() //马上启动触发器
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                        .repeatSecondlyForever(5) //5秒后重复执行
                        .withRepeatCount(3))  //只重复3次,默认值是0

                .startAt(startDate) //设置任务的开始时间
                .endAt(endDate)  //设置任务的结束时间
                .build();

        //4.让调度器关联任务和触发器,保证按照触发器定义的条件执行任务
        scheduler.scheduleJob(jobDetail,trigger);

        //5.启动调度器
        scheduler.start();
    }
}

9.4 quartz CronTrigger代码

9.4.1 HelloJobCronTrigger.java

Job类

package com.tangguanlin.quartz;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
 * 说明:
 * 作者:汤观林
 * 日期:2021年06月14日 02时
 */
public class HelloJobCronTrigger implements Job{

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

        //输出当前时间
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateStr = sdf.format(date);

        //工作内容
        System.out.println("正在进行数据库的备份工作,备份数据库的时间是:"+ dateStr);
    }
}

9.4.2 HelloSchedulerDemoCronTrigger.java

调度类

package com.tangguanlin.quartz;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.util.Date;

/**
 * 说明:
 * 作者:汤观林
 * 日期:2021年06月13日 18时
 */
public class HelloSchedulerDemoCronTrigger {

    public static void main(String[] args) throws SchedulerException {

        //1.调度器(scheduler)从工厂中获取调度实例
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

        //设置任务的开始时间
        Date startDate = new Date();
        //任务的开始时间推迟3s
        startDate.setTime(startDate.getTime()+3000);

        //设置任务的结束时间
        Date endDate = new Date();
        //任务的结束时间推迟10秒
        endDate.setTime(endDate.getTime()+10000);

        //2.任务实例(JobDetail)
        //加载任务类,与HelloJob完成绑定
        JobDetail jobDetail = JobBuilder.newJob(HelloJobCronTrigger.class)
                .withIdentity("job1", "group1") //参数1:任务名称(唯一性) 参数2:任务组的名称
                .build();

        //3.触发器(Trigger) .withSchedule(SimpleScheduleBuilder.simpleSchedule().repeatSecondlyForever(5)) //每5秒执行一次
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger1", "group1") //参数1:触发器的名称(唯一性) 参数2:触发器组的名称
                .startNow() //马上启动触发器
                .withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * 14 6 ?"))//日历
                //.startAt(startDate) //设置任务的开始时间
                //.endAt(endDate)  //设置任务的结束时间
                .build();

        //4.让调度器关联任务和触发器,保证按照触发器定义的条件执行任务
        scheduler.scheduleJob(jobDetail,trigger);

        //5.启动调度器
        scheduler.start();
    }
}

10 定时任务表达式

网站:
https://cron.qqe2.com/
https://www.bejson.com/othertools/cron/

常用表达式例子
  (10/2 * * * * ?   表示每2秒 执行任务
  (10 0/2 * * * ?    表示每2分钟 执行任务
  (10 0 2 1 * ?   表示在每月的1日的凌晨2点调整任务
  (20 15 10 ? * MON-FRI   表示周一到周五每天上午10:15执行作业
  (30 15 10 ? 6L 2002-2006   表示2002-2006年的每个月的最后一个星期五上午10:15执行作
  (40 0 10,14,16 * * ?   每天上午10点,下午2点,4点 
  (50 0/30 9-17 * * ?   朝九晚五工作时间内每半小时 
  (60 0 12 ? * WED    表示每个星期三中午12点 
  (70 0 12 * * ?   每天中午12点触发 
  (80 15 10 ? * *    每天上午10:15触发 
  (90 15 10 * * ?     每天上午10:15触发 
  (100 15 10 * * ?    每天上午10:15触发 
  (110 15 10 * * ? 2005    2005年的每天上午10:15触发 
  (120 * 14 * * ?     在每天下午2点到下午2:59期间的每1分钟触发 
  (130 0/5 14 * * ?    在每天下午2点到下午2:55期间的每5分钟触发 
  (140 0/5 14,18 * * ?     在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 
  (150 0-5 14 * * ?    在每天下午2点到下午2:05期间的每1分钟触发 
  (160 10,44 14 ? 3 WED    每年三月的星期三的下午2:102:44触发 
  (170 15 10 ? * MON-FRI    周一至周五的上午10:15触发 
  (180 15 10 15 * ?    每月15日上午10:15触发 
  (190 15 10 L * ?    每月最后一日的上午10:15触发 
  (200 15 10 ? * 6L    每月的最后一个星期五上午10:15触发 
  (210 15 10 ? * 6L 2002-2005   2002年至2005年的每月的最后一个星期五上午10:15触发 
  (220 15 10 ? * 6#3   每月的第三个星期五上午10:15触发


  (5)0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时
  (6)0 0 12 ? * WED 表示每个星期三中午12点
  (7)0 0 12 * * ? 每天中午12点触发
  (8)0 15 10 ? * * 每天上午10:15触发
  (9)0 15 10 * * ? 每天上午10:15触发
  (10)0 15 10 * * ? 每天上午10:15触发
  (11)0 15 10 * * ? 2005 2005年的每天上午10:15触发
  (12)0 * 14 * * ? 在每天下午2点到下午2:59期间的每1分钟触发
  (13)0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发
  (14)0 0/5 14,18 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
  (15)0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟触发
  (16)0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44触发
  (17)0 15 10 ? * MON-FRI 周一至周五的上午10:15触发
  (18)0 15 10 15 * ? 每月15日上午10:15触发
  (19)0 15 10 L * ? 每月最后一日的上午10:15触发
  (20)0 15 10 ? * 6L 每月的最后一个星期五上午10:15触发
  (21)0 15 10 ? * 6L 2002-2005 2002年至2005年的每月的最后一个星期五上午10:15触发
  (22)0 15 10 ? * 6#3 每月的第三个星期五上午10:15触发


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值