Quartz入门

1、Quartz可以用来做什么?

Quartz是一个任务调度框架,比如你遇到这样的问题:

  • 想每月25号,信用卡自动还款
  • 想每年4月1日自动给当年暗恋女神发一封匿名贺卡
  • 订单下单后未付款,15分钟后自动撤消订单,并自动解锁锁定的商品

这些问题总结起来就是:在某一个有规律的时间点干某件事。并且时间的触发的条件可以非常复杂(比如每月最后一个工作日的17:50),复杂到需要一个专门的框架来干这个事。 Quartz就是来干这样的事,你给它一个触发条件的定义,它负责到了时间点,触发相应的Job起来干活。

2、Quartz的触发器

触发器用来告诉调度程序作业什么时候触发,框架提供了5种触发器类型,但两个最常用的SimpleTriggerCronTrigger

五种类型的Trigger(定时器):SimpleTrigger,CronTirgger,DateIntervalTrigger,NthIncludedDayTrigger和Calendar类( org.quartz.Calendar)。

场景:

   简单调度器(SimpleTrigger):执行N次,重复N次

   表达式调度器(CronTrigger):几秒 几分 几时 哪日 哪月 哪周 哪年,执行

3、 存储方式

RAMJobStore(内存作业存储类型)和JDBCJobStore(数据库作业存储类型),两种方式对比如下:

quartz相关表达式:

在线生成表达式网址:http://cron.qqe2.com/

4、代码演示(包含简单调度器以及表达式触发器两类)

所需pom依赖:

      <dependency>
           <groupId>org.quartz-scheduler</groupId>
           <artifactId>quartz-jobs</artifactId>
           <version>2.2.1</version>
      </dependency>

具体作业类代码:

package com.zking.job;

import org.quartz.*;

/**
 * @author LJ
 * @site www.lijun.com
 * @Date 2019年02月23日
 * @Time 19:20
 */
public class RamJob implements Job {

    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("定时任务启动。。。。");
        JobDetail jobDetail = jobExecutionContext.getJobDetail();
        JobDataMap jobDataMap = jobDetail.getJobDataMap();
        System.out.println("定时任务参数:level-》" + jobDataMap.get("level") + ",name-》"
        + jobDataMap.get("name") + ",sex-》" + jobDataMap.get("sex"));
    }
}

执行作业类逻辑:

    public static void main(String[] args) throws SchedulerException {
        //创建调度工厂类实例StdSchedulerFactory
        StdSchedulerFactory sc = new StdSchedulerFactory();
        //创建调度器实例Scheduler
        Scheduler scheduler = sc.getScheduler();
        //创建任务详情JobDetail
        JobDetail jobDetail = newJob(RamJob.class)
                .withIdentity("detail1","group1")//组成唯一标识
                .withDescription("this is a jobDetail")
                //向具体执行的作业类传值方式一
                .usingJobData("level","admin")
                .build();

        //向具体执行的作业类传值方式二
        JobDataMap jobDataMap = jobDetail.getJobDataMap();
        jobDataMap.put("name","zs");
        jobDataMap.put("sex","man");

        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger1","group1")
                .withDescription("this is a trigger")
                //简单调度器:每四秒执行一次,共执行三次
                .withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(3,4))
                //表达式调度器:每五秒执行一次
//                .withSchedule(CronScheduleBuilder.cronSchedule("*/5 * * * * ?"))
                .build();

        //注入作业类以及触发器到调度器中
        scheduler.scheduleJob(jobDetail,trigger);
        //启动调度器
        scheduler.start();
    }

运行效果:

这个例子很好的覆盖了Quartz最重要的3个基本要素:

  • Scheduler:调度器。所有的调度都是由它控制。
  • Trigger: 定义触发的条件。
  • JobDetail & Job: JobDetail 定义的是任务数据,而真正的执行逻辑是在Job中,例子中是RamJob。 为什么设计成JobDetail + Job,不直接使用Job?这是因为任务是有可能并发执行,如果Scheduler直接使用Job,就会存在对同一个Job实例并发访问的问题。而JobDetail & Job 方式,sheduler每次执行,都会根据JobDetail创建一个新的Job实例,这样就可以规避并发访问的问题。

5、spring自带的定时任务

缺点:单线程执行

package com.zking.job;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

/**
 * @author LJ
 * @site www.lijun.com
 * @Date 2019年02月23日
 * @Time 20:19
 */
@Service
public class SpringTask {

    @Scheduled(cron = "0/5 * * * * ?")
    public void test(){
        System.out.println("测试spring自带的定时任务。。。。");
        try {
            Thread.sleep(10*1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("定时任务结束。。。。");
    }
}
package com.zking;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@EnableScheduling
@SpringBootApplication
public class Quartz01Application {

    public static void main(String[] args) {
        SpringApplication.run(Quartz01Application.class, args);
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值