使用quartz进行定时作业调度

quartz.properties:位于classpath目录

# 配置主调度器属性  
org.quartz.scheduler.instanceName=QuartzScheduler  
org.quartz.scheduler.instanceId=AUTO  
# 配置线程池  
# Quartz线程池的实现类  
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool  
# 线程池的线程数量,配置为1一个任务最多起一个线程,如果下一次调度来临时上一次任务未执行完,则下一次任务会延迟执行。
org.quartz.threadPool.threadCount=1  
# 线程池里线程的优先级  
org.quartz.threadPool.threadPriority=5
# 配置作业存储  
org.quartz.jobStore.misfireThreshold=60000  
org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore

主程序:负责配置调度器、触发器、任务细节

import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;
import java.text.SimpleDateFormat;
import java.util.Date;
import job.MyJob;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;
​
public class Main {public static void main(String[] args) throws SchedulerException {
        Main start = new Main();
        start.go();
    }
​
    public void go() throws SchedulerException {
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
​
        JobDetail job1 = newJob(MyJob.class).withIdentity("job1", "group1").build();
        Trigger trigger1 = newTrigger().withIdentity("trigger1", "group1").withSchedule(cronSchedule("1,2,3 * * * * ?")).build();
​
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date1 = scheduler.scheduleJob(job1, trigger1);
        System.out.println(df.format(date1));
​
        scheduler.start();
​
        try {
            Thread.sleep(60 * 1000L);
        } catch (Exception e) {
            e.printStackTrace();
        }
​
        scheduler.shutdown(true);
        int n = scheduler.getMetaData().getNumberOfJobsExecuted();
        System.out.println(n);
    }
}

具体的任务执行类,要实现Job接口:

import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
​
public class MyJob implements Job{
    private boolean isRunning = false;
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        String jobName = context.getJobDetail().getKey().getName();

        if(!isRunning){
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            System.out.println(jobName + "  ___________  " + df.format(new Date()));
            isRunning = true;
        }else{
            System.out.println("MyJob is already running!");
        }
    }
}

分析:

//首先,一个完整的调度程序分三部分:任务、调度器、触发器。
//调度器的作用是负责调度整个调度程序的启动,停止。和按照触发器的触发信号来调度任务的运行。
//触发器就像一个计时器,按照提前指定的规则触发执行信号。
//任务自然是实际要完成的工作。

//程序中先创建一个调度器: 
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//让调度程序开始
scheduler.start();
//让调度程序结束 
scheduler.shutdown(true);
//返回调度器一共调度执行任务的次数。
scheduler.getMetaData().getNumberOfJobsExecuted();
//把触发器和任务添加到调度器中,调度器就会按照定义好的触发器的触发信号来执行定义好的任务。
//这个方法返回任务的第一次调用时间。
//当然如果此时还没调用start()方法任务不会执行,但是会在调用start()方法时立即补上执行应执行而未执行的那几次任务。
scheduler.scheduleJob(job1, trigger1);
​
​
//创建一个名字为job1,分组为group1的任务,任务的定义为MyJob类。
JobDetail job1 = newJob(MyJob.class).withIdentity("job1", "group1").build();
//其中newJob方法是org.quartz.JobBuilder类的一个静态方法,这里用了import static静态引入。
//每一个任务都是一个MyJob类的对象实例。要求MyJob类有个无参构造方法。//创造一个名字为trigger1,分组为group1的触发器,按照cron表达式指定的规则触发执行信号。
Trigger trigger1 = newTrigger().withIdentity("trigger1", "group1").withSchedule(cronSchedule("1,2,3 * * * * ?")).build();
//其中newTrigger方法是org.quartz.TriggerBuilder类的一个静态方法,这里用了import static静态引入。
//触发器分两种,一种是简单触发器,一种是cron触发器,上面用的第二种,手动指定cron表达式

定义一个简单触发器,简单触发器只能指定什么时候执行第一次,间隔多久执行下一次,和一共重复执行几次:

import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
//立即开始执行,并每间隔2s执行一次,共重复3次,所以任务一共会执行4次(第1次和重复3次)。
trigger1 = newTrigger()
                .withIdentity("trigger1", "group1")
                .startAt(new Date())
                .withSchedule(
                        simpleSchedule()
                        .withIntervalInSeconds(2)// 重复间隔2s
                        .withRepeatCount(3)) // 重复次数3次,若一直重复用.repeatForever()
                .build();

可以看出newTrigger方法返回一个TriggerBuilder类,这个类通过一些方法进行触发器配置,最后调用build方法返回构造的触发器。(以上用的链式写法)
而简单触发器或cron触发器并没有本质区别,只是在配置的时候传入withSchedule方法的参数不同,当然定时规则也可能不同。

猜你喜欢

转载自blog.csdn.net/xuejianbest/article/details/80405128
今日推荐