Quartz--概述、简单使用

简介

Quartz是一个任务调度框架,是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。

比如你遇到这样的问题:

  1. 每个月29号,信用卡自动还款
  2. 每年4月1日给自己暗恋女神发一封匿名贺卡
  3. 每个1小时,备份一下自己的学习笔记

这些问题总结起来就是:在某一个有规律的时间点做某事。并且时间的触发条件可以非常复杂(比如每月最后一个工作日的17:50),复杂到需要一个专门的框架来干这个事情。

Quartz就是来专门干这个事情的,你给它一个触发条件的定义,它负责到指定时间点,触发对应的Job起来干活。如果应用程序需要在给定时间执行任务,或者如果系统有连续维护作业,那么Quartz是最理想的解决方案。

特点

  • 作业调度:作业被安排在一个给定的触发时间运行。触发器可以使用下列指令的组合来创建:

    • 在一天中的某个时间(到毫秒)
    • 在一周的某几天
    • 在每月的某一天
    • 在一年中的某些日期
    • 不在注册的日历中列出的特定日期(如商业节假日除外)
    • 重复特定次数
    • 重复进行,直到一个特定的时间/日期
    • 无限重复
    • 重复的延迟时间间隔
  • 作业持久性:Quartz的设计包括一个作业存储接口,有多种实现。

    • 通过使用包含JDBCJobStore,所有的作业和触发器配置为『非挥发性』都存储在通过JDBC关系数据库
    • 通过使用包含的RAMJobStore,所有的作业和触发器存储在RAM,因此不计划执行仍然存在——但这是无需使用外部数据库的优势
配置
#名为:quartz.properties,放在classpath下,如果没有此配置则按默认配置启动

# 指定调度器名称,非实现类
org.quartz.scheduler.instanceName = DefaultQuartzScheduler04
# 指定线程池实现类
org.quartz.threadPool.class = org.quartz.simple.SimpleThreadPool
# 线程池线程数量
org.quartz.threadPool.threadCount = 10
# 优先级,默认5
org.quartz.threadPool.threadPriority = 5
# 非持久化job
org.quartz.jobStore.class = org.quartz.simple.RAMJobStore

核心类说明

Scheduler

Scheduler:调度器,所有的调度都由它控制,Scheduler就是Quartz的大脑,所有任务都是由它来设置。

Schduler包含两个重要的组件:JobStore和ThreadPool

  • JobStore是会来存储运行时信息的,包括Trigger,Schduler,JobDetail,业务锁等
  • ThreadPool就是线程池,Quartz有自己的线程池实现。所有任务都会由线程池执行

SchdulerFactory,顾名思义就是用来创建Schduler,有两个实现DiretSchedulerFactory和StdSchdulerFactory。前者可以用来在代码里定制你自己的Schduler参数。后者是直接读取classpath下的quartz.properties(不存在就使用默认值)配置来实例化Schduler。通常来讲,使用StdSchdulerFactory也就足够了。

SchdulerFactory本身是支持创建stub的,可以用来管理远程的Scheduler,功能和本地一致。

Trigger
SimpleTrigger

指定从某一个时间开始,以一定的时间间隔(单位是毫秒)执行的任务。
它适合的任务类似于:9:00开始,每隔1小时,执行一次
它的属性有:

  • repeatInterval:重复间隔
  • repeatCount:重复次数。实际执行次数是repeatCount + 1。因为在startTime的时候一定会执行一次。

示例:

SimpleScheduleBuiler.simpleSchedule()
		.withIntervalSeconds(10)//每隔10秒执行一次
		.repeatForever()//永远执行
		build();

SimpleScheduleBuiler.simpleSchedule()
		.withIntervalInMinutes(3)//每隔3分钟执行一次
		.withRepeatCount(3)//执行3次
		build();
CalendarIntervalTrigger

类似于SimpleTrigger,指定从某一个时间开始,以一定的时间间隔执行的任务。但是不同的是SimpleTrigger指定的时间间隔为毫秒,没办法指定每隔一个月执行一次(每月的时间间隔不是固定值),而CalendarIntervalTrigger支持的间隔单位有秒,分钟,小时,天,月,年,星期。

CalendarIntervalScheduleBuilder.calendarIntervalSchedule()
		.withIntervalInDays(2)//每2天执行一次
		.build();

CalendarIntervalScheduleBuilder.calendarIntervalSchedule()
		.withIntervalInWeeks(1)//每周执行一次
		.build();
DailyTimeIntervalTrigger

指定每天的某个时间段内,以一定的时间间隔执行任务,并且它可以支持指定星期。它合适的任务类似于:指定每天9:00至18:00,每隔70秒执行一次,并且只要周一至周五执行。

它的属性有:

  • startTimeOfDay:每天开始时间
  • endTimeOfDay:每天结束时间
  • daysOfWeek:需要执行的星期
  • interval:执行间隔
  • intervalUnit:执行间隔的单位(秒,分钟,小时,天,月,年,星期)
  • repeatCount:重复次数

示例:

DailyTimeIntervalScheduleBuilder.dailyTimeIntervalSchedule()
           .startingDailyAt(TimeOfDay.hourAndMinuteOfDay(9, 0))//每天9:00开始
           .endingDailyAt(TimeOfDay.hourAndMinuteOfDay(18, 0))//每天18:00结束
           .onDaysOfTheWeek(DateBuilder.MONDAY, DateBuilder.TUESDAY)//周一和周二
           .withIntervalInHours(1)//每隔1小时执行一次
           .withRepeatCount(100)//最多重复100次(实际执行101次)
           .build();


DailyTimeIntervalScheduleBuilder.dailyTimeIntervalSchedule()
           .startingDailyAt(TimeOfDay.hourAndMinuteOfDay(9, 0))//每天9:00开始
           .endingDailyAfterCount(10)//每天执行10次后结束,这个方法实际上根据startTimeOfDay+interval*count=endTimeOfDay
           .onDaysOfTheWeek(DateBuilder.MONDAY, DateBuilder.TUESDAY)//周一和周二
           .withIntervalInHours(1)//每隔1小时执行一次
           .build();
CronTrigger

适合于更复杂的任务,它支持类型Linux Cron的语法(并且更强大)。基本上它覆盖了以上三个Trigger的绝大部分能力(但不是全部)。它适合的任务类似于:每天0:00,9:00,18:00各执行一次。它的属性只有一个:Cron表达式

示例:

CronScheduleBuilder.cronSchedule("0/10 * * * * ?").build();
简单使用

依赖:

<dependencies>
    <dependency>
      <groupId>org.quartz-scheduler</groupId>
      <artifactId>quartz</artifactId>
      <version>2.2.3</version>
    </dependency>
  </dependencies>

Job

public class MyJob implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        //创建工作详情
        JobDetail jobDetail = jobExecutionContext.getJobDetail();
        //获取工作的名称
        String name = jobDetail.getKey().getName();//任务明
        String group = jobDetail.getKey().getGroup();//任务group
        String data = jobDetail.getJobDataMap().getString("data");//任务中的数据
        System.out.println("job执行,job名:" + name + " group:" + group + " data:" + data + new Date());
    }
}
private static void test01() throws SchedulerException {
        //创建scheduler调度器,核心组件
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        //定义一个Trigger,触发条件类
        TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger();
        //创建触发器trigger
        Trigger trigger = triggerBuilder.withIdentity("trigger1", "group1")//定义name/group
                .startNow()//一旦加入scheduler立即生效,即开始时间
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                        .withIntervalInSeconds(1)//一秒执行一次
                        .repeatForever())//一直执行,直到结束
                        //可以设置结束时间,如果不设置,则一直执行
                        .endAt(new GregorianCalendar(2021,5,5,16,7,0).getTime())
                .build();
        //定义一个JobDetail
        //定义Job类为MyJob类,这是真正的执行逻辑所在
        JobDetail job = JobBuilder.newJob(MyJob.class)
                .withIdentity("测试任务1", "test")//定义name/group
                .usingJobData("data", "jobData_xxxxxx")//定义属性,存储数据
                .build();
        //调度器中假如任务和触发器
        scheduler.scheduleJob(job, trigger);
        //启动任务调度
        scheduler.start();

        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //关闭调度器
        scheduler.shutdown();
    }
```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值