作业调度哪种方式好,最终选了Quartz
随着云平台,大数据等的出现,用户或潜在访问者越来越想免费体验产品,特别是想申请系统(比如开虚拟机,启动docker等),可是系统硬件资源有限,那怎么才能让用户实际操作云平台资源呢,那就是免费三天或七天的使用期(也有是一天的使用期),若过期了不花钱续费,系统就要自动清理云环境申请的资源(好多云厂商都是如此,比如某云,免费试用到期了,会发邮件t提醒续费),这时就用到了作业调度的功能,这就要用定时器(它可以当做定时的任务,到期会执行,就像闹钟),java生态中有原生的定时器库,也有第三方的比如Quartz,
下面我就用例子说明下如何使用
1. java的原生定时器组件Timer和TimerTask
Timer是一种定时器工具,用来在一个后台线程计划执行指定任务,它可以计划执行一个任务一次或反复多次。
Timer类中常见方法
而TimerTask是一个抽象类,实现了Runnable接口,所以也就具备多线程的能力,它的子类代表一个可以被Timer计划的任务。
下面是一个简单的例子,编写任务代码
编写测试代码
测试结果如图:
注意此方法schedule和scheduleAtFixedRate的区别:
虽然jdk原生能实现需要的定时清理功能,查阅了资料后发现还有更好的方法,接着往下看
2. ScheduledExecutorService(一个接口)
ScheduledExecutorService,是基于线程池设计的定时任务类,每个调度任务都会分配到线程池中的一个线程去执行,也就是说,任务是并发执行,互不影响。
一个小例子如下
编写要执行的线程任务
测试定时任务执行
注意scheduleAtFixedRate和scheduleWithFixedDelay:
:
这个scheduledexecutorservice似乎是不错,我又想有没有更好的调度框架,这时又找到了Quartz(也是我现实中用到的定时调度库)
3. Quartz要登场了,强大无比
简单介绍下,Quarzt是一个项目中定时执行任务的开源项目,Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。它的结构图如图示:
job任务类:表示的任务是什么(比如自定义的任务种类比如清理试用账号申请的资源),需要定时执行代码的类。
JobDetail:配置任务类的细节,即注入任务类和指定任务类的方法,是一个可执行的工作,它本身可能是有状态的。
trigger:即触发器,代表一个调度参数的配置,配置调用的时间,表示何时触发job任务。
调度工厂(scheduler):是一个计划调度器容器,容器里面可以盛放众多的JobDetail和trigger,当容器启动后,里面的每个JobDetail都会根据trigger按部就班自动去执行。
下面以案例说下如何使用(由于我不是单独使用的,是和spring整合使用)
创建自定义job类(伪代码)
然后再spring配置任务类的bean和配置触发器(时间)
最后配置调度工厂并且注入配置好的触发器
现在可以启动测验了,测试时可以调整触发时间(比如每分钟),下面是con表达式样板
小结:
1. Timer在执行定时任务时只创建一个线程。
2. Timer线程并不捕获异常,TimerTask抛出的未检查的异常会终止timer线程,导致剩下的任务没法执行(这很不好)。
3. ScheduledExecutorService
继承于ExecutorService,
ScheduledThreadPool内部是线程池,支持多个任务并发执行.
4. Quartz很灵活,和spring集成的很好。
d...........
Timer&TimerTask→→→→→ScheduledExecutorService(体系复杂)→→→→→Quartz
参考:
0. Java Timer vs ExecutorService?
1 https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ScheduledExecutorService.html
2. 几种任务调度的 Java 实现方法与比较: https://www.ibm.com/developerworks/cn/java/j-lo-taskschedule/
3. cron表达式生成工具: http://cron.qqe2.com/