quartz2.3.0(五)制定错过执行任务的misfire策略

感谢兄台: 《quartz-misfire 错失、补偿执行

misfire定义

misfire:被错过的执行任务策略

misfire重现——CronTrigger

job任务类:

package org.quartz.examples.example5;

import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.PersistJobDataAfterExecution;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * <pre>
 * 任务job。
 * 因为@DisallowConcurrentExecution注解,所以这个job不可以被多个定时器或触发器同时执行,否则会触发定时器的misfire,就需要我们定义好定时器的misfire策略。
 * 如果不定义misfire,会出现
 * </pre>
 */
@PersistJobDataAfterExecution  //持久化JobDataMap里的数据,使下一个定时任务还能获取到这些值
@DisallowConcurrentExecution  //禁止并发多任务执行,所以永远只有一个任务在执行中
public class StatefulDumbJob implements Job {

    //任务执行计数器
    public static final String NUM_EXECUTIONS = "NumExecutions";
    public static final String EXECUTION_DELAY = "ExecutionDelay";
    public static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

    //必须要有public修饰的无参构造函数
    public StatefulDumbJob() {
    }

    //定时器执行方法
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("---" + context.getJobDetail().getKey() + " executing.   [" + SDF.format(new Date()) + "]");
        //获得带状态集合
        JobDataMap map = context.getJobDetail().getJobDataMap();

        int executeCount = 0;
        if (map.containsKey(NUM_EXECUTIONS)) {
            executeCount = map.getInt(NUM_EXECUTIONS);
        }

        executeCount++;

        map.put(NUM_EXECUTIONS, executeCount);

        System.out.println("  -" + context.getJobDetail().getKey() + " complete (" + executeCount + ").[" + SDF.format(new Date())+ "]");

    }

}

定时器类:

package org.quartz.examples.example5;

import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.DateBuilder.nextGivenSecondDate;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;

import java.util.Date;

import org.quartz.CronExpression;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdScheduler;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <pre>
此类演示了如何定义定时器的misfire策略。misfire:被错过的执行任务策略
 * </pre>
 */
public class MisfireExample_CronScheduleBuilder {
    static final Logger LOG = LoggerFactory.getLogger(MisfireExample_CronScheduleBuilder.class);

    public static void main(String[] args) throws Exception {
        // 初始化一个调度工厂,并实例化一个调度类
        SchedulerFactory sf = new StdSchedulerFactory();
//                        Scheduler sched = sf.getScheduler();
        StdScheduler sched = (StdScheduler) sf.getScheduler();

        // 第一个参数:null就是默认当前时间,也可以指定时间
        // 第二个参数:把一分钟按10进行划分,也就是60/10等份。
        // 举例:当前时间是10:26:04,那么startTime就是10:30:00。当前时间是10:38:31,那么startTime就是10:40:00。
        Date startTime = nextGivenSecondDate(null, 10);
        JobDetail job = newJob(StatefulDumbJob.class).withIdentity("job1", "group1")
//                                .usingJobData(StatefulDumbJob.EXECUTION_DELAY, 30000L)
                .build();
        String cron = "0/2 * * * * ?"; // 每2秒执行一次

        CronScheduleBuilder cronScheduleBuilder = cronSchedule(new CronExpression(cron));

        // ========================================================================
        // ======================== misfire定义,开始 =======================
        // ========================================================================

        /*
         设置misfire策略:CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING = 2
         ——不触发立即执行
         ——等待下次Cron触发频率到达时刻开始按照Cron频率依次执行
         */
        cronScheduleBuilder.withMisfireHandlingInstructionDoNothing();

        /*
         设置misfire策略:Trigger.MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY = -1
         ——以错过的第一个频率时间立刻开始执行 ——重做错过的所有频率周期 ——当下一次触发频率发生时间大于当前时间以后,按照Interval的依次执行剩下的频率
         ——共执行RepeatCount+1次
         */
//        cronScheduleBuilder.withMisfireHandlingInstructionIgnoreMisfires(); 

        /*
         * 设置misfire策略:CronTrigger.MISFIRE_INSTRUCTION_FIRE_ONCE_NOW = 1
         * 以当前时间为触发频率立刻触发一次执行,然后按照Cron频率依次执行
         */
//        cronScheduleBuilder.withMisfireHandlingInstructionFireAndProceed(); 

        // ========================================================================
        // ======================== misfire定义,结束 =======================
        // ========================================================================

        CronTrigger trigger = newTrigger().withIdentity("trigger1", "group1").startAt(startTime)
                .withSchedule(cronScheduleBuilder).build();

        // CronTrigger默认misfire策略是: org.quartz.Trigger.MISFIRE_INSTRUCTION_SMART_POLICY = 0
        int misfireInstruction = trigger.getMisfireInstruction();
        LOG.info("当前misfire策略:" + misfireInstruction);

        Date ft = sched.scheduleJob(job, trigger);
        LOG.info(job.getKey().toString());

        sched.start();
        LOG.info("调度器启动,主线程睡眠15秒!!!!调度器内任务线程继续执行。");
        Thread.sleep(15L * 1000L);

//        // 暂停触发器
//        sched.pauseTrigger(trigger.getKey());
//        // 继续触发器
//        sched.resumeTrigger(trigger.getKey());

        // 暂停执行任务
        sched.pauseJob(job.getKey());
        LOG.info("调度器暂停执行定时器,主线程睡眠11秒!!!!会错过执行job1的N次定时任务。模拟当定时器的执行线程由于抢不到CPU时间或其他事件错过执行的情况。");
        Thread.sleep(11L * 1000L);
        // 继续执行任务
        sched.resumeJob(job.getKey()); //当定时器得到继续执行的命令时,被错过执行的任务次数,就会按照misfire的定义去执行

        LOG.info("调度器继续执行定时器,主线程睡眠15秒!!!!调度器内任务线程继续执行。");
        Thread.sleep(15L * 1000L);

        LOG.info("调度器终止执行!!!!");
        sched.shutdown(true);
    }

}

原文地址:https://www.cnblogs.com/zhuwenjoyce/p/11184882.html

时间: 2024-07-31 19:08:32

quartz2.3.0(五)制定错过执行任务的misfire策略的相关文章

深入struts2.0(五)--Dispatcher类

1.1.1       serviceAction方法 在上个Filter方法中我们会看到如下代码: this.execute.executeAction(request, response, mapping); 图3.2.1  Filter方法中跳转到action图 而在ExecuteOperations类中(excute是一个实例)有如下代码: public void executeAction(HttpServletRequest request, HttpServletResponse

quartz2.3.0(十)xml配置方式定义quartz定时任务

1.新增pom依赖 除了按照<quartz2.3.0系列目录——带您由浅入深全面掌握quartz2.3.0>添加依赖之外,pom.xml里新增加依赖: <dependency> <groupId>opensymphony</groupId> <artifactId>quartz-all</artifactId> <version>1.6.3</version> </dependency> <d

java线程池与五种常用线程池策略使用与解析

背景:面试中会要求对5中线程池作分析.所以要熟知线程池的运行细节,如CachedThreadPool会引发oom吗? java线程池与五种常用线程池策略使用与解析 可选择的阻塞队列BlockingQueue详解 首先看一下新任务进入时线程池的执行策略: 如果运行的线程少于corePoolSize,则 Executor始终首选添加新的线程,而不进行排队.(如果当前运行的线程小于corePoolSize,则任务根本不会存入queue中,而是直接运行) 如果运行的线程大于等于 corePoolSize

Linux对外提供服务 网络连接 端口操作 1.开启服务监听端口 2.设置防火墙,放行访问端口的包 iptables&amp;netfilter 四表五链和通堵策略

应用举例: Linux上安装Tomcat后,客户端要能够访问服务器上的Tomcat 操作: 1.网络操作 本机必须能够ping通目标主机(本地虚拟机或者远程主机) 2.端口操作 1.开启服务监听端口 2.设置防火墙,放行访问该端口的数据包 关键iptables和netfilter: iptables中的四表五链和堵通策略 CentOS6.7端口操作最佳实践: 查看iptables命令的帮助: iptables --help 不详细 man iptables 一般详细 手册页 info iptab

app运营:如何制定消息推送策略?

app运营:如何制定消息推送策略? 今天,在队内,我做了一次关于app消息推送策略设计的分享,在这里整理出来,也算一个知识梳理过程,供各位批评指正. 很多app设计者总是很贪婪,想要攫取用户的眼球,于是就不停地通知,还有一些app本身很nice,却因为那些没完没了的通知变得让人讨厌.如何打磨一个好的app消息推送策略,对一个app的体验而已至关重要. 在一个移动操作系统的生态中,app可以实现一个功能,叫做消息推送,即通知(push).通知是能够起到提醒或者唤醒用户的作用的,也是app运营最优质

最新版本号cocos2d&amp;#173;2.0&amp;#173;x&amp;#173;2.0.2使用新资源载入策略!不再沿用-hd、-

?? 前段时间cocos2dx更新了最新版本号cocos2d-2.0-x-2.0.2.也从这个版本号開始对于资源载入与管理都改变了策略. 在之前的载入方式都是通过沿用与cocos2d-iphone一样的载入资源方式,对于图片名后加入-hd,-ipad,-ipadhd方式,当用户开启项目的高清视网膜后就能够默认寻找相应的资源.可是从cocos2d-2.0-x-2.0.2版本号開始,资源载入策略不在如此了.对跨平台整合不清楚的请看cocos2dx最新2.x版本号跨平台整合NDK+Xcode 最新资源

quartz2.3.0(十五)执行、暂停、继续执行、清除,花式操作数据库中持久化的job任务

前提准备: 先在数据库中建立quartz需要的11张表(我这里用的是Oracle数据库),根据不同的数据库quartz分别提供了不同的初始化sql文件,sql文件路径在 quartz-2.3.0-SNAPSHOT-0724\src\org\quartz\impl\jdbcjobstore下: ScheduleBuilder是trigger触发器的触发规则定制类,旗下有4种触发器实现类:  CalendarIntervalScheduleBuilder.CronScheduleBuilder.Da

quartz2.3.0(八)使用日历排除不应该执行任务的时间段

Job任务类 package org.quartz.examples.example8; import java.util.Date; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.JobK

angularjs2.0 五分钟入门教程之typescript版本

貌似没看到一个中文的讲解ng2入门五分钟教程,所以亲自整理了下整个入门教程的步骤,希望对后来者学习有所帮助.PS:我在win7中码的. 新建一个project目录,以下所有操作都在这个目录下进行. 1.安装tsd编译typescript代码命令工具 $ npm install -g [email protected]^0.6.0 2.安装angular2,es6-promiserx,rx,rx-lite $ tsd install angular2 es6-promise rx rx-lite