zoukankan      html  css  js  c++  java
  • quartz 浅谈 Scheduler

    1.Scheduler工厂模式

    所有的Scheduler实例应该由SchedulerFactory来创建

    2.SchedulerFactory类图

           

    通过StdSchedulerFactory或DirectSchedulerFactory的getDefaultScheduler获取Schedule对象。

        1、DirectSchedulerFactory是能对Scheduler绝对控制的。

    DirectSchedulerFactory factory=DirectSchedulerFactory.getInstance();//获取DirectSchedulerFactory对象
    
    factory.createVolatileScheduler(10);//通过调用createXXXX方法初始化Scheduler对象,但是该方法不返回Scheduler对象,createXXXX方法 用于设置Scheduler的属性
    Scheduler scheduler = factory.getScheduler();//获取Scheduler对象,如果不调用createXXXX方法会抛出SchedulerException异常

        2、STDSchedulerFactory类产生Scheduler实例。

          stdSchedulerFactory有三种方式向StdScheduler提供属性以供Scheduler使用:通过 java.util.Properties 实例提供、通过外部属性文件提供、通过含有

          属性文件内容的 java.io.InputStream 实例提供

            1、通过java.util.properties提供       

    StdSchedulerFactory factory = new StdSchedulerFactory();
    Properties props = new Properties(); 
    props.put(StdSchedulerFactory.PROP_THREAD_POOL_CLASS, "org.quartz.simpl.SimpleThreadPool");//实现org.quartz.spi.ThreadPool的类名 props.put("org.quartz.threadPool.threadCount", "10"); //线程数量 factory.initialize(props); //初始化 Scheduler scheduler = factory.getScheduler();

           可以通过public void initialize(String filename) throws SchedulerException方法来加载初始化Scheduler的属性

          2、通过public void initialize(InputStream propertiesStream) throws SchedulerException方法读取流的形式加载属性

          如果没有为initialize方法指定加载文件或流,那么StdSchedulerFactory会默认的从quartz.properties文件去加载

            3、可以用StdSchedulerFactory.getDefaultScheduler()方法来创建一个Scheduler实例

      Scheduler通过调用start方法启动工作的执行。

      Scheduler通过scheduleJob(JobDetail,Trigger)方法向Scheduler注册工作,JobDetail持有执行job的信息,trigger指的是什么时候触发工作。

       最常用的是StdSchedulerFactory工程类,其有两种创建Scheduler的方式:

                //3. 创建scheduler
                Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
                // 3. 创建scheduler
                SchedulerFactory sfact = new StdSchedulerFactory();
                Scheduler scheduler = sfact.getScheduler();

    3.   回顾Quartz三个核心概念

    调度器
    任务
    触发器           

     1个job对应多个Trigger

    4.Scheduler的创建方式


    StdSchedulerFactory:
      使用一组参数(Java.util.Properties)来创建和初始化Quartz调度器
      配置参数一般存储在quartz.properties中
      调用getScheduler方法就能创建和初始化调度器对象

    5..Scheduler的主要函数

    复制代码
    // 绑定 jobDetail 和 trigger,将它注册进 Scheduler 当中  ,返回值是最近一次任务执行的开始时间
    Date scheduleJob(JobDetail jobDetail, Trigger trigger)
    // 启动 Scheduler
    void start()
    // 暂停 Scheduler
    void standby()
    // 关闭 Scheduler
    void shutdown()
    复制代码

     例一:测试:scheduleJob函数返回最近一次开始执行的时间

    复制代码
    package cn.qlq.quartz;
    
    import static org.quartz.JobBuilder.newJob;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import org.quartz.CronScheduleBuilder;
    import org.quartz.CronTrigger;
    import org.quartz.JobDetail;
    import org.quartz.Scheduler;
    import org.quartz.SchedulerFactory;
    import org.quartz.TriggerBuilder;
    import org.quartz.impl.StdSchedulerFactory;
    
    public class HelloScheduler {
        public static void main(String[] args) {
            try {
                // 1. 创建一个JodDetail实例 将该实例与Hello job class绑定 (链式写法)
                JobDetail jobDetail = newJob(HelloJob.class) // 定义Job类为HelloQuartz类,这是真正的执行逻辑所在
                        .withIdentity("myJob") // 定义name/group
                        .build();
                // 打印当前的时间
                SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                Date date = new Date();
                System.out.println("current time is :" + sf.format(date));
    
                // 2. 2018年内每天11点18开始执行,每隔5s执行一次
                CronTrigger trigger = (CronTrigger) TriggerBuilder.newTrigger()
                        .withIdentity("myTrigger", "group1")// 定义名字和组
                        .withSchedule(    //定义任务调度的时间间隔和次数
                                CronScheduleBuilder
                                .cronSchedule("0/5 0 14,18 * * ? *")
                                )
                        .build();
    
                // 3. 创建scheduler
                SchedulerFactory sfact = new StdSchedulerFactory();
                Scheduler scheduler = sfact.getScheduler();
    
                // 4. 将trigger和jobdetail加入这个调度
    //            scheduler.scheduleJob(jobDetail, trigger);
    
                // 5. 启动scheduler
                scheduler.start();
                
                System.out.println("schedule time is:"+sf.format(scheduler.scheduleJob(jobDetail, trigger)));
                
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    复制代码

     结果:

    current time is :2018-04-05 11:42:42
    schedule time is:2018-04-05 02:00:00

    例二:测试standby()挂起Scheduler之后3s后再次开启Scheduler

    复制代码
    package cn.qlq.quartz;
    
    import static org.quartz.JobBuilder.newJob;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import org.quartz.CronScheduleBuilder;
    import org.quartz.CronTrigger;
    import org.quartz.JobDetail;
    import org.quartz.Scheduler;
    import org.quartz.SchedulerFactory;
    import org.quartz.TriggerBuilder;
    import org.quartz.impl.StdSchedulerFactory;
    
    public class HelloScheduler {
        public static void main(String[] args) {
            try {
                // 1. 创建一个JodDetail实例 将该实例与Hello job class绑定 (链式写法)
                JobDetail jobDetail = newJob(HelloJob.class) // 定义Job类为HelloQuartz类,这是真正的执行逻辑所在
                        .withIdentity("myJob") // 定义name/group
                        .build();
                // 打印当前的时间
                SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                Date date = new Date();
                System.out.println("current time is :" + sf.format(date));
    
                // 2. 2018年内每天11点18开始执行,每隔5s执行一次
                CronTrigger trigger = (CronTrigger) TriggerBuilder.newTrigger()
                        .withIdentity("myTrigger", "group1")// 定义名字和组
                        .withSchedule(    //定义任务调度的时间间隔和次数
                                CronScheduleBuilder
                                .cronSchedule("* * * * * ? *")
                                )
                        .build();
    
                // 3. 创建scheduler
                SchedulerFactory sfact = new StdSchedulerFactory();
                Scheduler scheduler = sfact.getScheduler();
    
                // 4. 将trigger和jobdetail加入这个调度
                scheduler.scheduleJob(jobDetail, trigger);
    
                // 5. 启动scheduler
                scheduler.start();
                
                //scheduler执行2s后挂起
                Thread.sleep(2000);
                scheduler.standby();
                //scheduler挂起3s后再次启动scheduler
                Thread.sleep(3000);
                scheduler.start();
                
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    复制代码

    结果:

    复制代码
    current time is :2018-04-05 11:49:28
    current exec time is :2018-04-05 11:49:28
    current exec time is :2018-04-05 11:49:29
    current exec time is :2018-04-05 11:49:30
    current exec time is :2018-04-05 11:49:33
    current exec time is :2018-04-05 11:49:33
    current exec time is :2018-04-05 11:49:33
    current exec time is :2018-04-05 11:49:34
    current exec time is :2018-04-05 11:49:35
    ....
    复制代码

    例三:测试shutdown函数(shutdown之后不能再次调用start重启,会报错)

    shutdown(true)表示等待所有正在执行的任务执行完毕后关闭Scheduler
    shutdown(false),即shutdown()表示直接关闭Scheduler

    (1)Job中睡眠5s钟

    复制代码
    package cn.qlq.quartz;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import org.quartz.Job;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    
    public class HelloJob implements Job {
        
    
        public void execute(JobExecutionContext context) throws JobExecutionException {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            //打印当前的时间
            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            Date date = new Date();
            System.out.println("current exec time is :"+sf.format(date));
        }
        
    }
    复制代码

    shutdown传入true参数:(在程序执行完之后才杀死Scheduler)

    复制代码
    package cn.qlq.quartz;
    
    import static org.quartz.JobBuilder.newJob;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import org.quartz.CronScheduleBuilder;
    import org.quartz.CronTrigger;
    import org.quartz.JobDetail;
    import org.quartz.Scheduler;
    import org.quartz.SchedulerFactory;
    import org.quartz.TriggerBuilder;
    import org.quartz.impl.StdSchedulerFactory;
    
    public class HelloScheduler {
        public static void main(String[] args) {
            try {
                // 1. 创建一个JodDetail实例 将该实例与Hello job class绑定 (链式写法)
                JobDetail jobDetail = newJob(HelloJob.class) // 定义Job类为HelloQuartz类,这是真正的执行逻辑所在
                        .withIdentity("myJob") // 定义name/group
                        .build();
                // 打印当前的时间
                SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                Date date = new Date();
                System.out.println("current time is :" + sf.format(date));
    
                // 2. 2018年内每天11点18开始执行,每隔5s执行一次
                CronTrigger trigger = (CronTrigger) TriggerBuilder.newTrigger()
                        .withIdentity("myTrigger", "group1")// 定义名字和组
                        .withSchedule(    //定义任务调度的时间间隔和次数
                                CronScheduleBuilder
                                .cronSchedule("* * * * * ? *")
                                )
                        .build();
    
                // 3. 创建scheduler
                SchedulerFactory sfact = new StdSchedulerFactory();
                Scheduler scheduler = sfact.getScheduler();
    
                // 4. 将trigger和jobdetail加入这个调度
                scheduler.scheduleJob(jobDetail, trigger);
    
                // 5. 启动scheduler
                scheduler.start();
                
                //scheduler执行2s后挂起
                Thread.sleep(2000);
                scheduler.shutdown(true);
                //shutdown(true)表示等待所有正在执行的任务执行完毕后关闭Scheduler
                //shutdown(false),即shutdown()表示直接关闭Scheduler
                System.out.println("scheduler is shutdown?"+scheduler.isShutdown());
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    复制代码

    结果:

    current time is :2018-04-05 11:58:25
    current exec time is :2018-04-05 11:58:30
    current exec time is :2018-04-05 11:58:31
    current exec time is :2018-04-05 11:58:32
    scheduler is shutdown?true

    shutdown传入false参数:(立即杀死Scheduler)

    复制代码
    package cn.qlq.quartz;
    
    import static org.quartz.JobBuilder.newJob;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import org.quartz.CronScheduleBuilder;
    import org.quartz.CronTrigger;
    import org.quartz.JobDetail;
    import org.quartz.Scheduler;
    import org.quartz.SchedulerFactory;
    import org.quartz.TriggerBuilder;
    import org.quartz.impl.StdSchedulerFactory;
    
    public class HelloScheduler {
        public static void main(String[] args) {
            try {
                // 1. 创建一个JodDetail实例 将该实例与Hello job class绑定 (链式写法)
                JobDetail jobDetail = newJob(HelloJob.class) // 定义Job类为HelloQuartz类,这是真正的执行逻辑所在
                        .withIdentity("myJob") // 定义name/group
                        .build();
                // 打印当前的时间
                SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                Date date = new Date();
                System.out.println("current time is :" + sf.format(date));
    
                // 2. 2018年内每天11点18开始执行,每隔5s执行一次
                CronTrigger trigger = (CronTrigger) TriggerBuilder.newTrigger()
                        .withIdentity("myTrigger", "group1")// 定义名字和组
                        .withSchedule(    //定义任务调度的时间间隔和次数
                                CronScheduleBuilder
                                .cronSchedule("* * * * * ? *")
                                )
                        .build();
    
                // 3. 创建scheduler
                SchedulerFactory sfact = new StdSchedulerFactory();
                Scheduler scheduler = sfact.getScheduler();
    
                // 4. 将trigger和jobdetail加入这个调度
                scheduler.scheduleJob(jobDetail, trigger);
    
                // 5. 启动scheduler
                scheduler.start();
                
                //scheduler执行2s后挂起
                Thread.sleep(2000);
                scheduler.shutdown(false);
                //shutdown(true)表示等待所有正在执行的任务执行完毕后关闭Scheduler
                //shutdown(false),即shutdown()表示直接关闭Scheduler
                System.out.println("scheduler is shutdown?"+scheduler.isShutdown());
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    复制代码

    结果:

    复制代码
    current time is :2018-04-05 12:00:11
    scheduler is shutdown?true
    current exec time is :2018-04-05 12:00:17
    current exec time is :2018-04-05 12:00:17
    current exec time is :2018-04-05 12:00:18
    current exec time is :2018-04-05 12:00:19
    复制代码
  • 相关阅读:
    【BZOJ】【1833】【ZJOI2010】count 数字计数
    bzoj2588: Spoj 10628. Count on a tree(树上第k大)(主席树)
    NOIP2017金秋冲刺训练营杯联赛模拟大奖赛第一轮Day2题解
    NOIP2017金秋冲刺训练营杯联赛模拟大奖赛第二轮Day2题解
    51nod 1962 区间计数(单调栈+二分)
    51nod 1486 大大走格子(DP+组合数学)
    bzoj2276: [Poi2011]Temperature(单调队列/堆)
    5028: 小Z的加油店(线段树)
    bzoj2216: [Poi2011]Lightning Conductor(分治决策单调性优化)
    bzoj1057: [ZJOI2007]棋盘制作(悬线法)
  • 原文地址:https://www.cnblogs.com/laosunlaiye/p/9406784.html
Copyright © 2011-2022 走看看