- 921. Minimum Add to Make Parentheses Valid 使括号有效的最少添加
- 915. Partition Array into Disjoint Intervals 分割数组
- 932. Beautiful Array 漂亮数组
- 940. Distinct Subsequences II 不同的子序列 II
感谢兄台: 《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);
}
}
misfire重现——SimpleTrigger
CronTrigger的misfire策略经本人亲自测试,注释全部可靠,SimpleTrigger全部来自以下兄台文章注释,实际结果请各位亲自实验。
感谢兄台: 《quartz-misfire 错失、补偿执行》
SimpleTrigger默认misfire策略也是: org.quartz.Trigger.MISFIRE_INSTRUCTION_SMART_POLICY = 0
//定义触发器,2秒执行一次,循环5次,总共执行6次
SimpleScheduleBuilder simpleScheduleBuilder = simpleSchedule().withIntervalInSeconds(2).withRepeatCount(5);
// .repeatForever(); //无限循环
/*
设置misfire策略为:SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT = 5
——不触发立即执行
——等待下次触发频率周期时刻,执行至FinalTime的剩余周期次数
——以startTime为基准计算周期频率,并得到FinalTime
——即使中间出现pause,resume以后保持FinalTime时间不变
*/
simpleScheduleBuilder.withMisfireHandlingInstructionNextWithExistingCount();
/*
设置misfire策略为:SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT = 4
——不触发立即执行
——等待下次触发频率周期时刻,执行至FinalTime的剩余周期次数
——以startTime为基准计算周期频率,并得到FinalTime
——即使中间出现pause,resume以后保持FinalTime时间不变
*/
simpleScheduleBuilder.withMisfireHandlingInstructionNextWithRemainingCount();
/*
设置misfire策略为:SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT = 3
——以当前时间为触发频率立即触发执行
——执行至FinalTIme的剩余周期次数
——以调度或恢复调度的时刻为基准的周期频率,FinalTime根据剩余次数和当前时间计算得到
——调整后的FinalTime会略大于根据starttime计算的到的FinalTime值
*/
simpleScheduleBuilder.withMisfireHandlingInstructionNowWithRemainingCount();
/*
设置misfire策略为:SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT = 2
——以当前时间为触发频率立即触发执行
——执行至FinalTIme的剩余周期次数
——以调度或恢复调度的时刻为基准的周期频率,FinalTime根据剩余次数和当前时间计算得到
——调整后的FinalTime会略大于根据starttime计算的到的FinalTime值
*/
simpleScheduleBuilder.withMisfireHandlingInstructionNowWithExistingCount();
/*
设置misfire策略为:SimpleTrigger.MISFIRE_INSTRUCTION_FIRE_NOW = 1
——以当前时间为触发频率立即触发执行
——执行至FinalTIme的剩余周期次数
——以调度或恢复调度的时刻为基准的周期频率,FinalTime根据剩余次数和当前时间计算得到
——调整后的FinalTime会略大于根据starttime计算的到的FinalTime值
*/
simpleScheduleBuilder.withMisfireHandlingInstructionFireNow();
/*
设置misfire策略为:Trigger.MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY = -1
——以错过的第一个频率时间立刻开始执行
——重做错过的所有频率周期
——当下一次触发频率发生时间大于当前时间以后,按照Interval的依次执行剩下的频率
——共执行RepeatCount+1次
*/
simpleScheduleBuilder.withMisfireHandlingInstructionIgnoreMisfires();
我想做的是分派(dispatch)一个 Job,然后在前一个 Job 完成后继续分派(dispatch)同一个 Job,这样就可以连续循环分派(dispatch) Job。如选项一所示,这以前是与数据
我想知道当一个过程通过一个作业执行时会发生什么,在它完成之前是作业调用该过程的下一次执行的时间。这是我创建的工作: DECLARE X NUMBER; BEGIN SYS.DB
我使用以下代码显示超时为 120 秒的 PowerShell 作业的结果。我想通过合并 Write-Progress(基于完成的作业数)来增强此代码。我尝试使用 this example然而,作为引用
我使用以下代码显示超时为 120 秒的 PowerShell 作业的结果。我想通过合并 Write-Progress(基于完成的作业数)来增强此代码。我尝试使用 this example然而,作为引用
这个关于 ECMAScript 规范(ECMA-262 第 8 版)的问题 这些天,我对作业和作业队列有点困惑。 这里有一些问题。 1:在ECMA-262中,有两种作业队列。一个是 ScriptJob
子进程是作业的一部分,由创建作业的进程启动。父进程尚未设置作业属性以允许脱离作业。需要在 JOB 上设置“JOB_OBJECT_LIMIT_BREAKAWAY_OK”标志以允许子进程脱离作业,但未设置
有没有人有类似于Path's Android Priority Job Queue的iOS作业队列?他们不介意与社区分享?我是 iOS 的新手,所以我不确定平台本身是否提供这样的解决方案。在 Andr
我正在关注 this在 Heroku 上安排我的 Django cron 作业。 程序文件: web: gunicorn tango.wsgi --log-file - clock: python c
UI协同程序指南包含有关如何管理UI协同程序生命周期的section。它说明了我们应该创建一个顶级Job实例,并将复合协程上下文contextJob + UI传递给我们启动的所有协程: launch(
我在 Spark 上创建了一个 Master 和一个 Worker。然后我创建了一个 Spark 流作业并尝试提交它,但在 Master 上它显示了一长串 java 错误 使用此命令启动主控: spa
我必须在 Spring Batch 上设置 jobparemeters,但使用 Spring Boot Batch 则无法轻松做到这一点。 我需要重新运行作业,但如果参数相同,spring-batch
众所周知,Apache Pig 是一种数据流语言。如果我编写了一个 Pig 脚本并且 Pig 决定拆分并运行两个或多个作业来执行手头的任务,那么 Pig 如何存储它从作业 1 传递到作业 2 的数据?
我以为他们指的是 Reducer 但在我的程序中我有 public static class MyMapper extends Mapper 和 public static class MyReduc
我需要创建一个恢复模式。 在我的模式中,我只能在给定的时间窗口内启 Action 业。 如果作业失败,它只会在下一个时间窗口重新启动,完成后我想开始为此窗口提前计划的计划作业。 作业之间的唯一区别是时
使用 play 框架 1.2.4 和 scala。我几乎没有类似的游戏工作 @OnApplicationStart class MyOtherJob extends Job { ... } @Ev
作业通知选项“作业成功时”和“作业完成时”有何区别。从表面上看,我假设“作业完成时”选项包含作业成功和作业失败,而“作业成功时”选项仅包含作业成功运行时。这是正确的吗? 最佳答案 作业成功时作业成功完
我正在尝试创建迁移,但由于以下错误而失败: Error from server (BadRequest): error when creating "kubernetes/migration-job.
Cron Job 和 hybris 中的 Job 有什么区别? 两者的创建/实现之间有什么区别? 最佳答案 下图描述了 Hybris 中 Jobs/Cronjobs 工作原理的完整 View
我正在运行多个作业,并且我希望每个作业都有一个单独的作业存储库(内存中实现)。 请在下面找到我尝试过的 bean 定义。请注意,我尝试指定具有作用域原型(prototype)的 bean。 我收到 j
Quartz 中是否有一种机制可以在启动另一个作业时删除现有作业?我需要暂停其他作业的原因是因为新作业需要所有资源可用,只有当其他作业未运行时才会如此。 这是一个示例: 我有 2 份工作:工作 A 和
我是一名优秀的程序员,十分优秀!