• Quartz入门


    Quartz简介及应用场景

    1. Quartz介绍

       任务调度框架“Quartz”是OpenSymphony开源组织在Job scheduling领域又一个开源项目,是完全由java开发的一个开源的任务日程管理系统,

       “任务进度管理器”就是一个在预先确定(被纳入日程)的时间到达时,负责执行(或者通知)其他软件组件的系统。

       

       简单来说就是实现“计划(或定时)任务”的系统,例如:订单下单后未付款,15分钟后自动撤消订单,并自动解锁锁定的商品

     

    2. Quartz的触发器

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

     

       五种类型的Trigger(定时器)

       SimpleTrigger,CronTirgger,DateIntervalTrigger,NthIncludedDayTrigger和Calendar类( org.quartz.Calendar)。

     

       场景:

       SimpleTrigger:执行N次,重复N次

       CronTrigger:几秒 几分 几时 哪日 哪月 哪周 哪年,执行

     

    3. 存储方式

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

      

                    优点                                    缺点

       RAMJobStore  不要外部数据库,配置容易,运行速度快    因为调度程序信息是存储在被分配给JVM的内存里面,

                                                            所以,当应用程序停止运行时,所有调度信息将被丢失。

                                                            另外因为存储到JVM内存里面,所以可以存储多少个Job和Trigger将会受到限制

     

       JDBCJobStor  支持集群,因为所有的任务信息都会保存    运行速度的快慢取决与连接数据库的快慢

                    到数据库中,可以控制事物,还有就是如

                    果应用服务器关闭或者重启,任务信息都

                    不会丢失,并且可以恢复因服务器关闭或

                    者重启而导致执行失败的任务   

    图解quartz工作流程

    quartz相关表达式

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

    所需pom依赖

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

    Quartz简单触发器 SimpleTrigger介绍

    每次执行 * 长时间,每次间隔 * 长时间

    package com.liuwenwu.quartz01.demo;
    
    import com.liuwenwu.quartz01.job.Ramjob;
    import org.quartz.*;
    import org.quartz.impl.StdSchedulerFactory;
    
    import static org.quartz.JobBuilder.newJob;
    
    
    /**
     * @author LWW
     * @site www.lww.com
     * @company
     * @create 2019-11-14 16:09
     *
     */
    public class Demo01 {
        public static void main(String[] args) throws SchedulerException {
            SchedulerFactory schemaFactory=new StdSchedulerFactory();
    //        调度器创建
            Scheduler scheduler = schemaFactory.getScheduler();
    //        具体定时任务需要执行的代码
            JobDetail jobDetail =newJob(Ramjob.class)
                    .withIdentity("job1","group1")
                    .withDescription("this is a job")
                    .build();
    
            Trigger trigger = (Trigger)TriggerBuilder.newTrigger()
                    //                重复3次间隔6秒
                    .withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(3,6))
                    //                触发器标识
                    .withIdentity("name1","group1")
                    .withDescription("this is a trigger")
                    .build();
            //       调度工厂绑定作业类及触发器
            scheduler.scheduleJob(jobDetail,trigger);
            scheduler.start();
        }
    }
    重复3次间隔6秒

    
    
    

    Quartz表达式触发器CronTirgger介绍

    package com.liuwenwu.quartz01.demo;
    
    import com.liuwenwu.quartz01.job.Ramjob;
    import org.quartz.*;
    import org.quartz.impl.StdSchedulerFactory;
    
    import static org.quartz.JobBuilder.newJob;
    
    
    /**
     * @author LWW
     * @site www.lww.com
     * @company
     * @create 2019-11-14 16:09
     *
     */
    public class Demo02 {
        public static void main(String[] args) throws SchedulerException {
            SchedulerFactory schemaFactory=new StdSchedulerFactory();
    //        调度器创建
            Scheduler scheduler = schemaFactory.getScheduler();
    //        具体定时任务需要执行的代码
            JobDetail jobDetail =newJob(Ramjob.class)
                    .withIdentity("job1","group1")
                    .withDescription("this is a job")
                    .build();
    
            Trigger trigger = (Trigger)TriggerBuilder.newTrigger()
                    //       定点16:30执行
                    .withSchedule(CronScheduleBuilder.cronSchedule("0 30 16 * * ?"))
                    //                触发器标识
                    .withIdentity("name1","group1")
                    .withDescription("this is a trigger")
                    .build();
            //       调度工厂绑定作业类及触发器
            scheduler.scheduleJob(jobDetail,trigger);
            scheduler.start();
        }
    }
    定点16:30执行

    package com.liuwenwu.quartz01.demo;
    
    import com.liuwenwu.quartz01.job.Ramjob;
    import org.quartz.*;
    import org.quartz.impl.StdSchedulerFactory;
    
    import static org.quartz.JobBuilder.newJob;
    
    
    /**
     * @author LWW
     * @site www.lww.com
     * @company
     * @create 2019-11-14 16:09
     *
     */
    public class Demo03 {
        public static void main(String[] args) throws SchedulerException {
            SchedulerFactory schemaFactory=new StdSchedulerFactory();
    //        调度器创建
            Scheduler scheduler = schemaFactory.getScheduler();
    //        具体定时任务需要执行的代码
            JobDetail jobDetail =newJob(Ramjob.class)
                    .withIdentity("job1","group1")
                    .withDescription("this is a job")
                    .build();
    
            Trigger trigger = (Trigger)TriggerBuilder.newTrigger()
                    //每3秒执行一次
                    .withSchedule(CronScheduleBuilder.cronSchedule("0/3 * * * * ?"))
                    //                触发器标识
                    .withIdentity("name1","group1")
                    .withDescription("this is a trigger")
                    .build();
            //       调度工厂绑定作业类及触发器
            scheduler.scheduleJob(jobDetail,trigger);
            scheduler.start();
        }
    }
    每3秒执行一次

    Quartz中参数传递

    package com.liuwenwu.quartz01.demo;
    
    import com.liuwenwu.quartz01.job.Ramjob;
    import org.quartz.*;
    import org.quartz.impl.StdSchedulerFactory;
    
    import static org.quartz.JobBuilder.newJob;
    
    
    /**
     * @author LWW
     * @site www.lww.com
     * @company
     * @create 2019-11-14 16:09
     *
     */
    public class Demo04 {
        public static void main(String[] args) throws SchedulerException {
            SchedulerFactory schemaFactory=new StdSchedulerFactory();
    //        调度器创建
            Scheduler scheduler = schemaFactory.getScheduler();
    //        具体定时任务需要执行的代码
            JobDetail jobDetail =newJob(Ramjob.class)
                    .withIdentity("job1","group1")
                    .withDescription("this is a job")
                    .usingJobData("name","zs")
                    .build();
    
            JobDataMap jobDataMap= jobDetail.getJobDataMap();
            jobDataMap.put("job","司机");
            jobDataMap.put("level","");
    
    
            Trigger trigger = (Trigger)TriggerBuilder.newTrigger()
                    //每3秒执行一次
                    .withSchedule(CronScheduleBuilder.cronSchedule("0/3 * * * * ?"))
                    //                触发器标识
                    .withIdentity("name1","group1")
                    .withDescription("this is a trigger")
                    .build();
            //       调度工厂绑定作业类及触发器
            scheduler.scheduleJob(jobDetail,trigger);
            scheduler.start();
        }
    }

    Ramjob

    package com.liuwenwu.quartz01.job;
    
    import org.quartz.Job;
    import org.quartz.JobDataMap;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    /**
     * @author LWW
     * @site www.lww.com
     * @company
     * @create 2019-11-14 16:06
     */
    public class Ramjob implements Job {
        @Override
        public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            System.err.println(format.format(new Date())+" :
    quartz定时任务启动......
    "); } }

    Spring task Vs Quartz

    Spring task

    优点:无需整合spring,作业类中就可以调用业务service

    缺点:单线程;不能做数据存储型的定时任务

    Quartz

    优点:多线程;可以做数据存储型的定时任务,维护性高;

    缺点:需要整合spring,不能直接调用业务层service;

    线程论证代码

    Spring task

    package com.liuwenwu.quartz01.task;
    
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Service;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    /**
     * @author LWW
     * @site www.lww.com
     * @company
     * @create 2019-11-14 16:43
     */
    
    @Service
    public class SprnigTask {
    
        @Scheduled(cron = "0/5 * * * * ?")
        public void xxx(){
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            System.err.println(format.format(new Date())+" : 这是一个spring task...");
    
            try {
                Thread.sleep(20*1000);
                System.out.println("我在处理大数据的耗时操作");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    Quartz01Application

    package com.liuwenwu.quartz01;
    
    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);
        }
    
    }

    结果是spring task中的定时任务变成了25s执行一次

    Quartz代码

    Demo04

    package com.liuwenwu.quartz01.demo;
    
    import com.liuwenwu.quartz01.job.Ramjob;
    import org.quartz.*;
    import org.quartz.impl.StdSchedulerFactory;
    
    import static org.quartz.JobBuilder.newJob;
    
    
    /**
     * @author LWW
     * @site www.lww.com
     * @company
     * @create 2019-11-14 16:09
     *
     */
    public class Demo04 {
        public static void main(String[] args) throws SchedulerException {
            SchedulerFactory schemaFactory=new StdSchedulerFactory();
    //        调度器创建
            Scheduler scheduler = schemaFactory.getScheduler();
    //        具体定时任务需要执行的代码
            JobDetail jobDetail =newJob(Ramjob.class)
                    .withIdentity("job1","group1")
                    .withDescription("this is a job")
                    .usingJobData("name","zs")
                    .build();
    
            JobDataMap jobDataMap= jobDetail.getJobDataMap();
            jobDataMap.put("job","司机");
            jobDataMap.put("level","");
    
    
            Trigger trigger = (Trigger)TriggerBuilder.newTrigger()
                    //每3秒执行一次
                    .withSchedule(CronScheduleBuilder.cronSchedule("0/3 * * * * ?"))
                    //                触发器标识
                    .withIdentity("name1","group1")
                    .withDescription("this is a trigger")
                    .build();
            //       调度工厂绑定作业类及触发器
            scheduler.scheduleJob(jobDetail,trigger);
            scheduler.start();
        }
    }

    Ramjob

    package com.liuwenwu.quartz01.job;
    
    import org.quartz.Job;
    import org.quartz.JobDataMap;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    /**
     * @author LWW
     * @site www.lww.com
     * @company
     * @create 2019-11-14 16:06
     */
    public class Ramjob implements Job {
        @Override
        public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            System.err.println(format.format(new Date())+" : 基于RAM的quartz调度框架定时任务...");
    
            try {
                Thread.sleep(10*1000);
                System.out.println("模拟正在处理大数据....");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    结果:不管前一个定时任务的线程是否结束,都会开启下一个线程,依然每10s执行一次;

  • 相关阅读:
    CodeForces 510C Fox And Names (拓扑排序)
    Codeforces 1153D Serval and Rooted Tree (简单树形DP)
    HDU 6437 Problem L.Videos (最大费用)【费用流】
    Luogu P3381 (模板题) 最小费用最大流
    Codeforces 741B Arpa's weak amphitheater and Mehrdad's valuable Hoses (并查集+分组背包)
    Codeforces 1144F Graph Without Long Directed Paths (DFS染色+构造)
    HDU 2204 Eddy's 爱好 (容斥原理)
    Codeforces 939E Maximize! (三分 || 尺取)
    Codeforces 938D. Buy a Ticket (最短路+建图)
    CodeForces 959E Mahmoud and Ehab and the xor-MST (MST+找规律)
  • 原文地址:https://www.cnblogs.com/liuwenwu9527/p/11867524.html
Copyright © 2020-2023  润新知