quartz详解2--jobDataMap

1. Job 和 JobDetail

Job接口,只有一个execute()方法。
源码:

package org.quartz;

public interface Job {
    void execute(JobExecutionContext var1) throws JobExecutionException;
}

我们开发者只要实现此接口,实现execute方法即可。把我们想做的事情,在execute中执行即可。

/ 1 / Job实例在quartz中的生命周期

每次调度器调度job时,在执行execute方法前都会创建新的job实例。
当调用完成后,关联的job实例会被释放,会GC回收。

/ 2 / JobDetail属性

JobDeailjob实例提供了许多设置属性,存储job实例的状态信息。调度器需要借助jobdetail对象来添加job实例。

属性:

  1. name
  2. group
  3. jobClass
  4. jobDataMap

解析:

JobDetail jobDetail = JobBuilder
                .newJob(PrintJob.class)
                .withIdentity("myjob","group1")
                .build();
System.out.println(jobDetail.getKey().getName());
System.out.println(jobDetail.getKey().getGroup());
System.out.println(jobDetail.getJobClass().getName());

说明:
每个JobDetailTriggernamegroup组成的key

显示信息:

myjob
group1(group不写则默认DEFALT)
cn.whbing.pro.quartz.PrintJob

2. JobExecuteContext

1.当scheduler调用一个job,就会将jobExecuteContext传递给job的execute方法。

2.job能够通过对象访问到quartz运行时候的环境以及job本身的明细数据。


3. jobDataMap

1.在进行任务调度时,jobDataMap存储在jobExecuteContext,非常方便获取。
2.jobDataMap可以用来存储任何可以序列化的数据对象,当job实例对象被执行时,这些参数对象会传递给它。
3.jobDataMap实现了Map接口。


4. 实验

目标:在scheduler中传入jobDataMap,在job中通过jobExecuteContext获取。
方法:在jobSchedulerTrigger上使用链式方法usingDataMap()绑定数据。

具体获取有两种方法:
方法一:在Map中获取
方法二:Job实现类中添加setter方法对应JobDataMap的键值(在初始化job实例时会自动调用setter方法)

/ 1 / 在JobDetailTrigger实例上绑定JobDataMap

 //1.创建JobDetail实例,并与printJob Class绑定
 JobDetail jobDetail = JobBuilder
         .newJob(PrintJob.class)
         .withIdentity("myjob","group1")
         .usingJobData("message","hello myjob1")
         .usingJobData("FloatJobValue",3.14F)
         .build();
 //2.定义Trigger实例,定义该job立即执行,并且每隔两秒重复执行一次,直到永远
 Trigger trigger = TriggerBuilder
         .newTrigger()
         .withIdentity("mytrigger","group1")
         .usingJobData("message","hello mytrigger1")
         .usingJobData("DoubleTriggerValue",5.21D)
         .startNow()...

方法1:通过Map获取

/ 2(A) / 在Job中通过context获取JobDetailTrigger本身信息,及JobDataMap信息

public class PrintJob implements Job {

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        //编写具体的业务逻辑即可
        //打印当前时间及hello
        LocalDateTime timeNow = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MM dd hh:mm:ss");
        System.out.println("execute time:"+formatter.format(timeNow));

        System.out.println("hello!");

        //获取jobDetail和trigger信息
        System.out.println("My job name and group:"
                        +context.getJobDetail().getKey().getName()
                        +","+context.getJobDetail().getKey().getGroup());
        System.out.println("My trigger name and group:"
                        +context.getTrigger().getKey().getName()
                        +","+context.getTrigger().getKey().getGroup());
        JobDataMap dataMap = context.getJobDetail().getJobDataMap();
        JobDataMap tdataMap = context.getTrigger().getJobDataMap();

        String message = dataMap.getString("message");
        System.out.println(message);
        //trigger和其他字段同理
    }
}

结果:

execute time:2018 07 30 08:04:25
hello!
My job name and group:myjob,group1
My trigger name and group:mytrigger,group1
hello myjob1

/ 2(B) / 在Job中通过context获取getMergedJobDataMap
(需保证jobDetail和Trigger中无重复key)

//通过getMergedJobDataMap获取jobdetail和trigger合并后的信息
JobDataMap data = context.getMergedJobDataMap();
//当有相同的key时,先获取jobdetail中的,trigger中的key会覆盖jobdetail
System.out.println(data.getString("message"));

结果:

hello mytrigger1

方法二:Job实现类中添加setter方法对应JobDataMap的键值
(需保证jobDetail和Trigger中无重复key)

说明:类自动注入(连注解都不需要),将通过反射直接将scheduler中的jobdetailtrigger中的jobDataMap的key,通过setter赋予对应字段(名称要相同)

public class PrintJob implements Job {

    private String message;
    private Float FloatJobValue;
    private Double DoubleTriggerValue;

    getter and setter...
    ...
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
       //直接通过setter后的字段访问
        System.out.println("直接通过字段访问1:"+message);
        System.out.println("直接通过字段访问2:"+FloatJobValue);
        System.out.println("直接通过字段访问3:"+DoubleTriggerValue);
    }

结果:(表明有相同字段时,这时以jobdetail为准)

直接通过字段访问1:hello myjob1
直接通过字段访问2:3.14
直接通过字段访问3:5.21
  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Quartz中,数据库集群是一种高可用性的解决方案。它允许多个Quartz实例共享同一个数据库,并且能够自动协调任务的执行,从而保证任务的可靠性和稳定性。 但是,在多个Quartz实例同时操作同一个数据库时,必须确保它们之间的数据一致性。这就需要使用锁机制来保证数据的正确性和安全性。 Quartz提供了两种类型的锁:悲观锁和乐观锁。它们分别采用不同的方式来保证数据的一致性。 1. 悲观锁 悲观锁是一种悲观的认为并发环境下会出现冲突的锁机制。它在操作数据时,会先加锁,然后再进行操作,操作完成后再释放锁。 在Quartz中,悲观锁是通过数据库中的行级锁来实现的。当一个Quartz实例要对某个任务进行操作时,它会先获取该任务的行级锁,然后再进行操作。其他实例在此期间无法获取该任务的锁,从而保证了数据的一致性。 2. 乐观锁 乐观锁是一种乐观的认为并发环境下不会出现冲突的锁机制。它在操作数据时,不会加锁,而是通过版本号等方式来判断数据是否发生了变化。 在Quartz中,乐观锁是通过版本号来实现的。每个任务都有一个版本号,当一个Quartz实例要对某个任务进行操作时,它会先获取该任务的版本号,然后进行操作。如果在此期间该任务的版本号发生了变化,则说明其他实例已经对该任务进行了操作,当前实例的操作会失败,需要重新获取版本号并重试。这样可以保证数据的一致性。 总的来说,悲观锁适用于高并发、数据冲突严重的场景,但是会带来较大的性能开销;而乐观锁适用于并发量较小、数据冲突不严重的场景,性能开销较小。在Quartz中,可以根据具体的业务需求选择合适的锁机制来保证数据的正确性和安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值