推广 热搜: csgo  vue  2023  angelababy  gps  信用卡  新车  htc  落地  控制 

核心组件、原理概述以及Job和这两个组件详解

   2023-06-18 网络整理佚名1520
核心提示:前文,我们已经聊完了的核心组件、原理概述以及Job和这两个组件详解如果你的很多(或者线程池的工作线程太少),可能没有足够的资源同时触发所有的;这种情况下,你可能希望控制哪些优先使用的工作线程,要达到该目的,可以在上设置属性。实例通过设置主要的属性,通过r设置与相关的属性。比如:如果你没有调用(…)方法,会为生成一个随机的名称;如果没有调用(…)方法,则默认使用当前时间,即立即生效。

在上一篇文章中,我们讲完了核心组件,原理概述,以及Job和这两个组件的详解。

现在继续往下:

如前所述,最常用的两种是:和

无论哪种方式,他们都有一些共同点

所有类型都有这个属性,代表身份; 除此之外,还有很多其他的共同属性。 这些属性可以在构建时设置。

的公共属性是:

优先事项()

如果你有很多(或者线程池中的线程太少),可能没有足够的资源同时触发所有的; 在这种情况下,您可能希望控制首先使用哪些工作线程。 为此,您可以在属性上进行设置。 比如你有N个线程需要同时触发,但是只有Z个线程,那么优先级最高的会先触发。 如果没有设置优先级,则使用默认优先级,值为5; 属性的值可以是任何整数,正数或负数。

注意:只有同时触发的才会比较优先级。 10:59 触发的总是在 11:00 触发的之前执行。

注意:如果是可恢复的,恢复后调度的时候,优先级和原来的一样。

失误()

还有一个重要的属性; 如果关闭了,或者线程池中没有可用的线程来执行作业,那么持久化的就会错过(miss)它的触发时间,也就是错过()。 不同的类型有不同的机制。 它们都默认使用“智能机制(smart)”,即根据类型和配置动态调整行为。 启动时,查询所有错过()的持久化。 然后根据各自的机制更新信息。 当您在项目中使用它时,您应该熟悉各种类型的机制,这些机制在 . 具体的机制会在具体的时候介绍。

日历示例()

对象(不是 java.util.)可以在定义和存储时关联。 用于从 的时间表中排除时间段。 例如,您可以创建一个在每个工作日上午 9:30 执行的一个,然后添加一个以排除所有商业假期。

任何实现该接口的可序列化对象都可以用作对象。 界面如下:

package org.quartz;
public interface Calendar {
  public boolean isTimeIncluded(long timeStamp);
  public long getNextIncludedTime(long timeStamp);
}

请注意,这些方法的参数类型很长。 正如您可能猜到的那样,它们是以毫秒为单位的时间戳。 即排除周期的单位可以精确到毫秒。 您可能对“排除一整天”比较感兴趣。 提供的 org..impl。 类可以很容易地实现。

必须先实例化,然后用()方法注册。 如果使用,在实例化后,需要调用(Date date)方法将时间段排除在日程表之外。 以下示例对多个实例使用相同的实例:

public class CornTest {
    public static void main(String[] args) throws SchedulerException {
        // 创建调度器
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
	   // 创建要排除的时间
        HolidayCalendar holidayCalendar = new HolidayCalendar();
        holidayCalendar.addExcludedDate(new Date());
        scheduler.addCalendar("hhh", holidayCalendar,false,false);
        // 创建任务实例
        JobDetail jobDetailA = JobBuilder.newJob(MyJob.class)
                .requestRecovery(false)
                .storeDurably(false)
                .withIdentity("helloA", "job")
                .usingJobData("xpA","好帅好帅")
                .build();
        // 创建触发器
        CronTrigger triggerA = TriggerBuilder.newTrigger()
                .withIdentity("triggerA", "trigger")
                .startNow()
                // 每2秒执行一次
                .withSchedule(CronScheduleBuilder.cronSchedule("0/3 * * * * ?"))
                .modifiedByCalendar("hhh")
                // 8s后结束
                .endAt(new Date(System.currentTimeMillis() + 8000))
                .build();
        // 调度器接管任务和触发器
        scheduler.scheduleJob(jobDetailA, triggerA);
        // 开始执行
        scheduler.start();
    }
}

#

可用于:在指定时间执行一次,从某个时间开始按一定时间间隔执行多次。

比如你可以设置一个在2022年4月28日晚上8点15分执行,或者在这个时间点每两分钟执行一次,重复5次。

属性包括:开始时间、结束时间、重复次数、重复间隔

唯一需要注意的是结束时间可能会影响重复次数。 有可能在重复次数达到设定值之前就到了结束时间。

通过r设置主要属性和相关属性来设置实例。

看下面的例子:从当前时间开始,每5s执行一次,重复两次

public class TestScheduler {
    public static void main(String[] args) throws SchedulerException {
        // 创建调度器
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        // 创建任务实例
        JobDetail jobDetailA = JobBuilder.newJob(MyJob.class)
                .requestRecovery(false)
                .storeDurably(false)
                .withIdentity("helloA", "job")
                .usingJobData("xpA","好帅好帅")
                .build();
        // 创建触发器
        SimpleTrigger triggerA = TriggerBuilder.newTrigger()
                .withIdentity("triggerA", "trigger")
                .startNow()
                // 每五秒执行一次,重复两次
                .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5).withRepeatCount(2))
                .build();
        // 调度器接管任务和触发器
        scheduler.scheduleJob(jobDetailA, triggerA);
        // 开始执行
        scheduler.start();
    }
}

你可以看到结果:

一共处死三人!

这是因为执行开始(即())不计入重复次数

我们再做一个测试,根据上面的要求加上一个结束时间:8秒结束:

SimpleTrigger triggerA = TriggerBuilder.newTrigger()
                .withIdentity("triggerA", "trigger")
                .startNow()
                // 每五秒执行一次,重复两次
                .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5).withRepeatCount(2))
                // 8s后结束
                .endAt(new Date(System.currentTimeMillis() + 8000))
                .build();

这次的结果是只执行了两次:

因为来不及重复第二次,就结束了。

(和其他人)将为未明确设置的属性选择合理的默认值。 例如:如果不调用(...)方法,会生成一个随机名称; 如果不调用(...)方法,默认使用当前时间,立即生效。

##策略(错过触发)

有几个相关的策略会告诉您在发生这种情况时该怎么做。

以下是未命中触发策略常量:

MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY
MISFIRE_INSTRUCTION_FIRE_NOW
MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT
MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT
MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT
MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT

配置的时候可以选择er中使用哪种策略

默认使用智能策略(smart),根据实例的配置和状态,在所有策略中动态选择一个策略。

通常比 .

你知道玉米表情吗~

可以指定每天中午12点执行,每个月的星期几等,非常灵活强大

尽管如此,与 一样,有一个指定何时生效,还有一个(可选)指定何时停止计划。

cron 表达式

cron表达式介绍:

cron 表达式是由 5 或 6 个空格分隔并分为 6 或 7 个域的字符串。 每个域代表一种含义。 Cron 有以下两种语法格式:

(1) 小时 月 年

(2) 小时月

一、结构

玉米从左到右(以空格分隔):秒、分、时、月、日、月、周、日、年

2.各字段的含义

字段允许值允许的特殊字符

第二()

0~59的整数

, - * / 四个字符

观点()

0~59的整数

, - * / 四个字符

小时

从 0 到 23 的整数

, - * / 四个字符

日期()

从 1 到 31 的整数(但您需要考虑您所在月份的天数)

,- * ? /LWC 八字

从 1 到 12 的整数或 JAN-DEC

, - * / 四个字符

星期()

从 1 到 7 的整数或 SUN-SAT (1=SUN)

, - * ? /LC#八个字符

年份(可选,留空)(年份)

1970~2099

, - * / 四个字符

防范措施:

每个字段都使用数字,但也可以出现以下特殊字符,它们的含义是:

(1) * :表示匹配该字段的任意值。 如果该字段中使用*,则表示该事件将每分钟触发一次。

(2) ?:只能在和两个域中使用。 它也匹配域的任何值,但它不匹配。 因为和会互相影响。 比如你想在每个月的20号触发调度,不管20号是星期几,你只能用13 13 15 20 * ?,其中最后一位只能用? ,而不是用*,如果用*表示无论星期几都会触发,就不是这样了。

(3)-:表示范围。比如在字段中使用5-20,表示从5分钟到20分钟每分钟触发一次

(4)/:表示从开始时间开始触发,以后每隔固定时间触发。 例如域中使用5/20表示每5分钟触发一次,而25、45等分别触发一次。

(5),: 表示列出枚举值。 例如:在字段中使用5,20,表示每分钟在5和20分钟触发。

(6) L:表示最后一个,只能出现在和字段中。 如果字段中使用5L,则表示将在最后一个星期四触发。

(7) W:表示有效工作日(周一至周五),只能出现在字段中,系统会在距离指定日期最近的有效工作日触发事件。 例如:使用5W时,如果5号是星期六,则在最近的工作日:星期五,即4号触发。 如果5号是周日,则在6号(周一)触发; 如果5号是周一到周五的某一天,则在5号触发。 还有一点,W 的最近一次查找不会跨越数月。

(8)LW:这两个字可以并用,表示某月的最后一个工作日,即最后一个星期五。

(9)#:用于确定每个月的星期几,只能出现在字段中。 例如4#2,表示某月的第二个星期三。

3.常用表达示例

(0) 0/20 * * * * ? 表示任务每20秒触发一次

(1) 0 0 2 1 * ? 表示每月1号凌晨2点调整任务

(2) 0 15 10 ? * MON-FRI表示job在周一到周五每天早上10:15执行

(3) 0 15 10 ? 6L 2002-2006 表示该操作在2002-2006每个月的最后一个周五上午10点15分执行

(4) 0 0 10,14,16 * * ? 每天上午 10 点、下午 2 点、下午 4 点

(5) 0 0/30 9-17 * * ? 朝九晚五的工作时间每半小时

(6) 0 0 12 ? * WED 指每周三中午 12 点

(7) 0 0 12 * * ? 每天中午12点触发

(8) 0 15 10 ? * * 每天上午 10:15 触发

(9) 0 15 10 * * ? 每天上午10点15分触发

(10) 0 15 10 * * ? * 每天上午10:15触发

(11) 0 15 10 * * ? 2005 2005年每天上午10点15分触发

(12) 0 * 14 * * ? 每天下午 2 点到 2 点 59 分每 1 分钟触发一次

(13) 0 0/5 14 * * ? 每天下午 2 点到 2:55 之间每 5 分钟触发一次

(14) 0 0/5 14,18 * * ? 每天下午 2 点到 2 点 55 分和下午 6 点到 6 点 55 分之间每 5 分钟触发一次

(15) 0 0-5 14 * * ? 每天下午2点到2点05分每1分钟触发一次

(16) 0 10,44 14 ? 3 WED 在每年三月的周三下午 2:10 和 2:44 触发

(17) 0 15 10 ? * MON-FRI 周一至周五上午 10:15 触发

(18) 0 15 10 15 * ? 每月15日上午10点15分触发

(19) 0 15 10 L* ? 每月最后一天上午 10:15 触发

(20) 0 15 10 ? * 6L 每月最后一个周五上午10:15触发

(21) 0 15 10 ? * 6L 在2月至2005年每个月的最后一个星期五上午10:15触发

(22) 0 15 10 ? * 6#3 在每个月的第三个星期五上午 10:15 触发

笔记:

(1) 一些子表达式可以包含范围或列表

例如:子表达式(day(week))可以是"MON-FRI", "MON, WED, FRI", "MON-WED, SAT"

“*”字符代表所有可能的值

因此,“”代表子表达式(month)中每个月的含义,“”代表子表达式(day(week))中星期几的含义

“/”字符用于指定值的增量

例如:子表达式()中的“0/15”表示从第0分钟开始,每15分钟

()子表达式中的“3/20”表示从第3分钟开始,每20分钟一次(与“3、23、43”意义相同)

这 ”?” 只用在day(month)和day(week)这两个子表达式中,表示没有指定值

当两个子表达式中的一个被赋值时,为了避免冲突,需要将另一个子表达式的值设置为“?”

“L”字符只用在日(月)和日(周)子表达式中,是单词“last”的缩写

但是它在两个子表达式中的含义是不同的。

在日(月)子表达式中,“L”表示该月的最后一天

在日(周)自我表达中,“L”表示一周的最后一天,也就是SAT

如果“L”前面有特定的东西,它有其他含义

例如:“6L”表示本月的最后6日,“FRIL”表示本月的最后一个星期五

注意:使用“L”参数时,不要指定列表或范围,因为这会导致问题

例子:

只需要稍作改动:

// 创建触发器
CronTrigger triggerA = TriggerBuilder.newTrigger()
    	.withIdentity("triggerA", "trigger")
    	.startNow()
    	// 每2秒执行一次
    	.withSchedule(CronScheduleBuilder.cronSchedule("0/3 * * * * ?"))
    	// 8s后结束
    	.endAt(new Date(System.currentTimeMillis() + 8000))
    	.build();

执行3次没有问题

阐明

错过的触发策略常量为

MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY
MISFIRE_INSTRUCTION_DO_NOTHING
MISFIRE_INSTRUCTION_FIRE_NOW

与错过触发不同,默认的智能策略(smart)被解释为立即触发。

您还可以在创建时指定一个错过的触发策略:

 
反对 0举报 0 收藏 0 打赏 0评论 0
 
更多>同类资讯
推荐图文
推荐资讯
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报
Powered By DESTOON