目录
Quartz可以用来做什么?
Scheduler
SchedulerFactory
JobDataMap
首页 Java java教程 Quartz可以用来做什么?

Quartz可以用来做什么?

May 22, 2018 am 09:28 AM
quartz

Quartz可以用来做什么?

Quartz是一个任务调度框架。比如你遇到这样的问题

  • 想每月25号,信用卡自动还款

  • 想每年4月1日自己给当年暗恋女神发一封匿名贺卡

  • 想每隔1小时,备份一下自己的爱情动作片 学习笔记到云盘

这些问题总结起来就是:在某一个有规律的时间点干某件事。并且时间的触发的条件可以非常复杂(比如每月最后一个工作日的17:50),复杂到需要一个专门的框架来干这个事。 Quartz就是来干这样的事,你给它一个触发条件的定义,它负责到了时间点,触发相应的Job起来干活。

废话不多说,代码杠杠的。。。

public static void main(String[] args) {     
try { 
//创建scheduler
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//定义一个Trigger
Trigger trigger =TriggerBuilder.newTrigger().withIdentity("trigger1", "group1") //定义name/group.startNow()//一旦加入scheduler,立即生效.
withSchedule(SimpleScheduleBuilder.simpleSchedule() //使用SimpleTrigger.withIntervalInSeconds(1) //每隔一秒执行一次.repeatForever()) //一直执行        
.build();
//定义一个JobDetail
JobDetail job =JobBuilder.newJob(HelloQuartz.class) //定义Job类为HelloQuartz类,这是真正的执行逻辑所在.withIdentity("job1", "group1") //定义name/group.usingJobData("name", "quartz") //定义属性        .build();
//加入这个调度    
scheduler.scheduleJob(job, trigger);
//启动之    
scheduler.start();
//运行一段时间后关闭 
Thread.sleep(10000);
      scheduler.shutdown(true);
   } catch (Exception e) {
    e.printStackTrace();
}

}
登录后复制

HelloQuartz类
登录后复制

public class HelloQuartz implements Job {public void execute(JobExecutionContext context) throws JobExecutionException {
        JobDetail detail = context.getJobDetail();
        String name = detail.getJobDataMap().getString("name");
        System.out.println("say hello to " + name + " at " + new Date());
    }
}
登录后复制

jar包:

这个例子很好的覆盖了Quartz最重要的3个基本要素:

  • Scheduler:调度器。所有的调度都是由它控制。

  • Trigger: 定义触发的条件。例子中,它的类型是SimpleTrigger,每隔1秒中执行一次(什么是SimpleTrigger下面会有详述)。

  • JobDetail & Job: JobDetail 定义的是任务数据,而真正的执行逻辑是在Job中,例子中是HelloQuartz。 为什么设计成JobDetail + Job,不直接使用Job?这是因为任务是有可能并发执行,如果Scheduler直接使用Job,就会存在对同一个Job实例并发访问的问题。而JobDetail & Job 方式,sheduler每次执行,都会根据JobDetail创建一个新的Job实例,这样就可以规避并发访问的问题。

Scheduler

Scheduler就是Quartz的大脑,所有任务都是由它来设施。

Schduelr包含一个两个重要组件: JobStore和ThreadPool。

JobStore是会来存储运行时信息的,包括Trigger,Schduler,JobDetail,业务锁等。它有多种实现RAMJob(内存实现),JobStoreTX(JDBC,事务由Quartz管理),JobStoreCMT(JDBC,使用容器事务),ClusteredJobStore(集群实现)、TerracottaJobStore(什么是Terractta)

ThreadPool就是线程池,Quartz有自己的线程池实现。所有任务的都会由线程池执行。

SchedulerFactory

SchdulerFactory,顾名思义就是来用创建Schduler了,有两个实现:DirectSchedulerFactory和 StdSchdulerFactory。前者可以用来在代码里定制你自己的Schduler参数。后者是直接读取classpath下的quartz.properties(不存在就都使用默认值)配置来实例化Schduler。通常来讲,我们使用StdSchdulerFactory也就足够了。

SchdulerFactory本身是支持创建RMI stub的,可以用来管理远程的Scheduler,功能与本地一样,可以远程提交个Job什么的。

1.job

实现类JobDetail

    JobDetail job = JobBuilder.newJob(RemindJob.class)
            .withIdentity("job1", "group1").build();//创建一个任务
     /**
      * 创建触发器
      * 第一种方式  不太好      */SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger", "myTriggerGroup").
    withSchedule(SimpleScheduleBuilder.simpleSchedule().
            withIntervalInSeconds(3).
            repeatForever()).
            startAt(new Date(System.currentTimeMillis()+1000)).build();    
    /**
     * 创建触发器
     * 第二种 方式  非常好
     * 可以 好用  2013年每月的第三个星期五上午10:30触发  0 30 10 ? * 6#3 2013
     * 2016年每月的第一个星期四下午16:17触发   0 17 16 ? * 5#1 2016
     * 每天15点到16点每5分钟运行一次,此外,每天17点到18点每5分钟运行一次  

     *//*CronTrigger trigger=TriggerBuilder.newTrigger() 
            .withIdentity("myTrigger", "myTriggerGroup")
            .withSchedule(CronScheduleBuilder.cronSchedule("0 18 16 ? * 5#1 2016")).build();*/
    SchedulerFactory sf=new StdSchedulerFactory();//创建调度者工厂Scheduler scheduler = sf.getScheduler();//创建一个调度者scheduler.scheduleJob(job,trigger);//注册并进行调度scheduler.start();//启动调度    //Thread.sleep(millis)    //scheduler.shutdown();//关闭调度
登录后复制

RemindJob 类的定义
登录后复制

 */public class RemindJob implements Job {private RemindService service=new RemindService();
    @Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {
        service.printPlan("你好!");
        
        Date date=new Date();
        String time = date.toString();
        System.out.println(time+"job is starting");
    }
登录后复制

可以看到,我们传给scheduler一个JobDetail实例,因为我们在创建JobDetail时,将要执行的job的类名传给了JobDetail,所以scheduler就知道了要执行何种类型的job;每次当scheduler执行job时,在调用其execute(…)方法之前会创建该类的一个新的实例;执行完毕,对该实例的引用就被丢弃了,实例会被垃圾回收;这种执行策略带来的一个后果是,job必须有一个无参的构造函数(当使用默认的JobFactory时);另一个后果是,在job类中,不应该定义有状态的数据属性,因为在job的多次执行中,这些属性的值不会保留。

那么如何给job实例增加属性或配置呢?如何在job的多次执行中,跟踪job的状态呢?答案就是:JobDataMap,JobDetail对象的一部分。

JobDataMap

JobDataMap中可以包含不限量的(序列化的)数据对象,在job实例执行的时候,可以使用其中的数据;JobDataMap是Java Map接口的一个实现,额外增加了一些便于存取基本类型的数据的方法。

将job加入到scheduler之前,在构建JobDetail时,可以将数据放入JobDataMap,如下示例:

    JobDetail job=JobBuilder.newJob(RemindJob.class)
            .withIdentity("job1", "group1")
            .usingJobData("hello", "we are family")
            .build();
登录后复制

在job的执行过程中,可以从JobDataMap中取出数据,如下示例:

@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {
        service.printPlan("你好!");
        JobKey key=context.getJobDetail().getKey();
        
        JobDataMap map = context.getJobDetail().getJobDataMap();
        String string = map.getString("hello");
        System.out.println(key+"==========="+string);
        
        Date date=new Date();
        String time = date.toString();
        System.out.println(time+"job is starting");
    }
登录后复制

如果你使用的是持久化的存储机制(本教程的JobStore部分会讲到),在决定JobDataMap中存放什么数据的时候需要小心,因为JobDataMap中存储的对象都会被序列化,因此很可能会导致类的版本不一致的问题;Java的标准类型都很安全,如果你已经有了一个类的序列化后的实例,某个时候,别人修改了该类的定义,此时你需要确保对类的修改没有破坏兼容性;更多细节,参考现实中的序列化问题。另外,你也可以配置JDBC-JobStore和JobDataMap,使得map中仅允许存储基本类型和String类型的数据,这样可以避免后续的序列化问题。

如果你在job类中,为JobDataMap中存储的数据的key增加set方法(如在上面示例中,增加setJobSays(String val)方法),那么Quartz的默认JobFactory实现在job被实例化的时候会自动调用这些set方法,这样你就不需要在execute()方法中显式地从map中取数据了。

在Job执行时,JobExecutionContext中的JobDataMap为我们提供了很多的便利。它是JobDetail中的JobDataMap和Trigger中的JobDataMap的并集,但是如果存在相同的数据,则后者会覆盖前者的值。

下面的示例,在job执行时,从JobExecutionContext中获取合并后的JobDataMap:

@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {
        service.printPlan("你好!");
        JobKey key=context.getJobDetail().getKey();        /*    JobDataMap map = context.getJobDetail().getJobDataMap();
        String string = map.getString("hello");
        System.out.println(key+"==========="+string);*/ JobDataMap map = context.getMergedJobDataMap();
         String string = map.getString("hello");
         System.out.println(key+"---------------------    "+string);
登录后复制

 

以上是Quartz可以用来做什么?的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

2025年的前4个JavaScript框架:React,Angular,Vue,Svelte 2025年的前4个JavaScript框架:React,Angular,Vue,Svelte Mar 07, 2025 pm 06:09 PM

本文分析了2025年的前四个JavaScript框架(React,Angular,Vue,Susve),比较了它们的性能,可伸缩性和未来前景。 尽管由于强大的社区和生态系统,所有这些都保持占主导地位,但它们的相对人口

如何使用咖啡因或Guava Cache等库在Java应用程序中实现多层缓存? 如何使用咖啡因或Guava Cache等库在Java应用程序中实现多层缓存? Mar 17, 2025 pm 05:44 PM

本文讨论了使用咖啡因和Guava缓存在Java中实施多层缓存以提高应用程序性能。它涵盖设置,集成和绩效优势,以及配置和驱逐政策管理最佳PRA

Java的类负载机制如何起作用,包括不同的类载荷及其委托模型? Java的类负载机制如何起作用,包括不同的类载荷及其委托模型? Mar 17, 2025 pm 05:35 PM

Java的类上载涉及使用带有引导,扩展程序和应用程序类负载器的分层系统加载,链接和初始化类。父代授权模型确保首先加载核心类别,从而影响自定义类LOA

Spring Boot Snakeyaml 2.0 CVE-2022-1471问题已修复 Spring Boot Snakeyaml 2.0 CVE-2022-1471问题已修复 Mar 07, 2025 pm 05:52 PM

本文介绍了SnakeyAml中的CVE-2022-1471漏洞,这是一个允许远程代码执行的关键缺陷。 它详细介绍了如何升级春季启动应用程序到Snakeyaml 1.33或更高版本的降低风险,强调了依赖性更新

Node.js 20:关键性能提升和新功能 Node.js 20:关键性能提升和新功能 Mar 07, 2025 pm 06:12 PM

Node.js 20通过V8发动机改进可显着提高性能,特别是更快的垃圾收集和I/O。 新功能包括更好的WebSembly支持和精制的调试工具,提高开发人员的生产率和应用速度。

冰山:数据湖桌的未来 冰山:数据湖桌的未来 Mar 07, 2025 pm 06:31 PM

冰山是用于大型分析数据集的开放式桌子格式,可提高数据湖的性能和可伸缩性。 它通过内部元数据管理解决了镶木quet/orc的局限

如何在Java中实施功能编程技术? 如何在Java中实施功能编程技术? Mar 11, 2025 pm 05:51 PM

本文使用lambda表达式,流API,方法参考和可选探索将功能编程集成到Java中。 它突出显示了通过简洁性和不变性改善代码可读性和可维护性等好处

如何共享黄瓜中的步骤之间的数据 如何共享黄瓜中的步骤之间的数据 Mar 07, 2025 pm 05:55 PM

本文探讨了在黄瓜步骤之间共享数据的方法,比较方案上下文,全局变量,参数传递和数据结构。 它强调可维护性的最佳实践,包括简洁的上下文使用,描述性

See all articles