ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

quartz(二)

2022-05-30 00:00:43  阅读:183  来源: 互联网

标签:execute quartz Worker 29 Trigger 2022.05 Hello


quartz(二)

通过官网案例,我们会有个疑惑,

  1. 为什么调度器(Scheduler)不直接调度任务(Job),而是由触发器(Trigger)去调度呢?是否可以在调度器直接指定一个规则直接调度job呢?

  2. 根据官网提供的案例,一共有四个名称指令,为什么会设计的这么麻烦?

首先回答第一个问题,既然任务是由Trigger触发,而不是Scheduler直接调度,那是否可以认为,一个任务可以有多个Trigger触发呢?下面通过代码演示验证我们的猜想.

根据上一篇的demo,我i们稍微改变一下代码,新增了一个Trigger

public class QuartzTest {
​
    public static void main(String[] args) {
​
        try {
​
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
​
            scheduler.start();
​
            JobDetail job = JobBuilder.newJob(HelloJob.class)
                    .withIdentity("job1", "group1")
                    .build();
            // 0 1 2 3
            Trigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity("trigger1", "group1")
                    .startNow()
                    .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                            .withIntervalInSeconds(1)
                            .repeatForever())
                    .build();
            //0 1
            Trigger trigger2 = TriggerBuilder.newTrigger()
                    .withIdentity("trigger2", "group2")
                    .forJob("job1", "group1")
                    .startNow()
                    .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                            .withIntervalInSeconds(3)
                            .repeatForever())
                    .build();
​
            scheduler.scheduleJob(job, trigger);
            scheduler.scheduleJob(trigger2);
​
            TimeUnit.SECONDS.sleep(3);
            scheduler.shutdown();
​
        } catch (Exception se) {
            se.printStackTrace();
        }
    }
}
​

trigger2会比trigger多一个forJob(),这么做是因为,我们在调度任务的时候,并不是每次都能拿到job这个对象的,所以增加forJob()指定从而触发这个job.

运行结果:

​
Hello.execute!!!2022.05.29 11:00:01 DefaultQuartzScheduler_Worker-2
Hello.execute!!!2022.05.29 11:00:01 DefaultQuartzScheduler_Worker-1
Hello.execute!!!2022.05.29 11:00:02 DefaultQuartzScheduler_Worker-3
Hello.execute!!!2022.05.29 11:00:03 DefaultQuartzScheduler_Worker-4
Hello.execute!!!2022.05.29 11:00:04 DefaultQuartzScheduler_Worker-5
Hello.execute!!!2022.05.29 11:00:04 DefaultQuartzScheduler_Worker-6
​
BUILD SUCCESSFUL in 5s
​
​

通过运行结果,我们发现,跑了很标准的6次,那我们怎么确定第一个Trigger跑了4次,第二个Trigger跑了2次呢?

此时我们修改一下HelloJob

public class HelloJob implements Job {
​
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
​
        StringJoiner stringJoiner = new StringJoiner("")
                .add("Hello.execute!!!")
                .add(DFUtil.format(new Date()))
                .add(Thread.currentThread().getName())
                .add(context.getTrigger().getKey().getName());
​
        System.out.println(stringJoiner);
    }
}

再次执行查看打印结果

Hello.execute!!!2022.05.29 11:05:06DefaultQuartzScheduler_Worker-2trigger2
Hello.execute!!!2022.05.29 11:05:06DefaultQuartzScheduler_Worker-1trigger1
Hello.execute!!!2022.05.29 11:05:07DefaultQuartzScheduler_Worker-3trigger1
Hello.execute!!!2022.05.29 11:05:08DefaultQuartzScheduler_Worker-4trigger1
Hello.execute!!!2022.05.29 11:05:09DefaultQuartzScheduler_Worker-5trigger1
Hello.execute!!!2022.05.29 11:05:09DefaultQuartzScheduler_Worker-6trigger2
​
Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.
​
You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
​
See https://docs.gradle.org/7.4.1/userguide/command_line_interface.html#sec:command_line_warnings
​
BUILD SUCCESSFUL in 5s

此时可以验证两个Trigger执行的次数;

那么此时的模型则变为了

一个Scheduler可以调度多个Trigger

那新的问题产生了,一个Trigger是否可以触发多个Job呢?

根据官方文档描述: Many Triggers can point to the same Job, but a single Trigger can only point to one Job

我们知道,一个Job可以被多个Trigger 触发,但是一个Trigger 只能触发一个Job;


下面解决第二个问题,关于JobDetail和Trigger的name和group;

首先,group是用来标记,方便管理的;name是用来标记的,既然name和group都是用来标记的,那也可以只用name去做标记就好了,看一下源码

 

    public TriggerBuilder<T> withIdentity(String name) {
        key = new TriggerKey(name, null);
        return this;
    }  

当我们把name和group设置为null时,

    public Key(String name, String group) {
        if(name == null)
            throw new IllegalArgumentException("Name cannot be null.");
        this.name = name;
        if(group != null)
            this.group = group;
        else
            this.group = DEFAULT_GROUP;
    }
    
    public static final String DEFAULT_GROUP = "DEFAULT";

此时我们发现,就算group设置为null,它也会默认传一个DEFAULT,这么做是为了什么呢?

Scheduler调度Trigger时有一个方法:scheduler.pauseJobs();它里面需要传入group组名,如果不传入,那么这一组任务就会暂停


Trigger的name和group明白了之后,我们看一下JobDetail的name和group的作用

我们可以试想这样的一个问题,根据官方文档说明,一个Job可以被多个Trigger触发,那么一个Job可不可以被多个Jobdetail引用呢?

我们再来修改一下代码,让Trigger触发Job,Trigger2触发Job2

public class QuartzTest3 {
​
    public static void main(String[] args) {
​
        try {
​
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
​
            scheduler.start();
​
            JobDetail job = JobBuilder.newJob(HelloJob.class)
                    .withIdentity("job1", "group1")
                    .build();
​
            JobDetail job2 = JobBuilder.newJob(HelloJob.class)
                    .withIdentity("job2", "group1")
                    .build();
​
            Trigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity("trigger1", "group1")
                    .startNow()
                    .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                            .withIntervalInSeconds(1)
                            .repeatForever())
                    .build();
​
            Trigger trigger2 = TriggerBuilder.newTrigger()
                    .withIdentity("trigger2", "group2")
                    .forJob("job2", "group1")
                    .startNow()
                    .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                            .withIntervalInSeconds(3)
                            .repeatForever())
                    .build();
​
            scheduler.scheduleJob(job, trigger);
            scheduler.scheduleJob(job2,trigger2);
​
            TimeUnit.SECONDS.sleep(3);
            scheduler.shutdown();
​
        } catch (Exception se) {
            se.printStackTrace();
        }
    }
}

运行结果

Hello.execute!!!2022.05.29 11:33:12DefaultQuartzScheduler_Worker-1trigger1
Hello.execute!!!2022.05.29 11:33:12DefaultQuartzScheduler_Worker-2trigger2
Hello.execute!!!2022.05.29 11:33:13DefaultQuartzScheduler_Worker-3trigger1
Hello.execute!!!2022.05.29 11:33:14DefaultQuartzScheduler_Worker-4trigger1
Hello.execute!!!2022.05.29 11:33:15DefaultQuartzScheduler_Worker-5trigger1
Hello.execute!!!2022.05.29 11:33:15DefaultQuartzScheduler_Worker-6trigger2
​
Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.
​
You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
​
See https://docs.gradle.org/7.4.1/userguide/command_line_interface.html#sec:command_line_warnings
​
BUILD SUCCESSFUL in 7s

通过代码结果,我们可以判定,quartz的真实模型如下

综上,我们可以获知:一个Job可以被多个Trigger 触发,但是一个Trigger 只能触发一个Job;一个Job可以被多个JobDetail所关联,不过我们在实际使用过程中,一个Job并不会被多个JobDetail所关联;实际生产中,还是以一个Job可以被多个Trigger 触发,一个JobDaetail只关联一个Job;因为生产过程中,不仅仅是自动触发任务,还需要手动去触发任务;

我们再次修改代码,将四个标记全部注释掉

public class QuartzTest4 {
​
    public static void main(String[] args) {
​
        try {
​
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
​
            scheduler.start();
​
            JobDetail job = JobBuilder.newJob(HelloJob.class)
//                    .withIdentity("job1", "group1")
                    .build();
​
            Trigger trigger = TriggerBuilder.newTrigger()
//                    .withIdentity("trigger1", "group1")
                    .startNow()
                    .withSchedule(SimpleScheduleBuilder.simpleSchedule() 
                            .withIntervalInSeconds(1)
                            .repeatForever())
                    .build();
​
            scheduler.scheduleJob(job, trigger);
​
            TimeUnit.SECONDS.sleep(3);
            scheduler.shutdown();
​
        } catch (Exception se) {
            se.printStackTrace();
        }
    }
}
​

运行结果

Hello.execute!!!2022.05.29 11:43:36DefaultQuartzScheduler_Worker-16da64b5bd2ee-f5a2f797-524c-44ab-802e-3833ccbc6433
Hello.execute!!!2022.05.29 11:43:37DefaultQuartzScheduler_Worker-26da64b5bd2ee-f5a2f797-524c-44ab-802e-3833ccbc6433
Hello.execute!!!2022.05.29 11:43:38DefaultQuartzScheduler_Worker-36da64b5bd2ee-f5a2f797-524c-44ab-802e-3833ccbc6433
Hello.execute!!!2022.05.29 11:43:39DefaultQuartzScheduler_Worker-46da64b5bd2ee-f5a2f797-524c-44ab-802e-3833ccbc6433
​
Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.
​
You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
​
See https://docs.gradle.org/7.4.1/userguide/command_line_interface.html#sec:command_line_warnings
​
BUILD SUCCESSFUL in 8s

随机生成了一个MD5的name值;

标签:execute,quartz,Worker,29,Trigger,2022.05,Hello
来源: https://www.cnblogs.com/wangshaoyun/p/16325375.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有