已注销用户的gravatar头像
已注销用户 2014-03-20 18:02:21

java中任务调度java.util.Timer,ScheduledExecutor,Quartz的机制说明和demo代码实例分享

    目前的 Web 应用,多数应用都具备任务调度的功能。这里就简单的介绍任务调度的Java 实现方法,主要包括 Timer,Scheduler, Quartz 以及 JCron Tab,目的在于给需要开发任务调度的牛牛们提供一个参考。

    1.Timer

    大部分已经非常熟悉 java.util.Timer 了,它是最简单的一种实现任务调度的方法,下面给出一个具体的例子:

    java中任务调度java.util.Timer,ScheduledExecutor,Quartz的机制说明和demo代码实例分享

     使用 Timer 实现任务调度的核心类是 Timer 和 TimerTask。其中 Timer 负责设定 TimerTask 的起始与间隔执行时间。使用者只需要创建一个 TimerTask 的继承类,实现自己的 run 方法,然后将其丢给 Timer 去执行即可。

Timer 的设计核心是一个TaskList 和一个TaskThread。Timer 将接收到的任务丢到自己的 TaskList中,TaskList 按照 Task 的最初执行时间进行排序。TimerThread 在创建 Timer 时会启动成为一个守护线程。这个线程会轮询所有任务,找到一个最近要执行的任务,然后休眠,当到达最近要执行任务的开始时间点,TimerThread 被唤醒并执行该任务。之后 TimerThread 更新最近一个要执行的任务,继续休眠。

Timer 的优点在于简单易用,但由于所有任务都是由同一个线程来调度,因此所有任务都是串行执行的,同一时间只能有一个任务在执行,前一个任务的延迟或异常都将会影响到之后的任务。

2.ScheduledExecutor

    鉴于 Timer 的上述缺陷,Java 5 推出了基于线程池设计的 ScheduledExecutor。其设计思想是,每一个被调度的任务都会由线程池中一个线程去执行,因此任务是并发执行的,相互之间不会受到干扰。需要注意的是,只有当任务的执行时间到来时,ScheduedExecutor 才会真正启动一个线程,其余时间 ScheduledExecutor 都是在轮询任务的状态。如下图:

    java中任务调度java.util.Timer,ScheduledExecutor,Quartz的机制说明和demo代码实例分享

ScheduledExecutorService 中两种最常用的调度方法 ScheduleAtFixedRate和 ScheduleWithFixedDelay。ScheduleAtFixedRate 每次执行时间为上一次任务开始起向后推一个时间间隔,即每次执行时间为 :initialDelay, initialDelay+period, initialDelay+2*period, …;ScheduleWithFixedDelay 每次执行时间为上一次任务结束起向后推一个时间间隔,即每次执行时间为:initialDelay, initialDelay+executeTime+delay, initialDelay+2*executeTime+2*delay。由此可见,ScheduleAtFixedRate 是基于固定时间间隔进行任务调度,ScheduleWithFixedDelay 取决于每次任务执行的时间长短,是基于不固定时间间隔进行任务调度。

 

3.ScheduledExecutor 和 Calendar 实现复杂任务调度

Timer 和 ScheduledExecutor 都仅能提供基于开始时间与重复间隔的任务调度,不能胜任更加复杂的调度需求。比如,设置每星期四的 17:20:00 执行任务。该功能使用 Timer 和 ScheduledExecutor 都不能直接实现,但我们可以借助 Calendar 间接实现该功能。

java中任务调度java.util.Timer,ScheduledExecutor,Quartz的机制说明和demo代码实例分享

 

以上例子实现了每星期四 17:20:00 执行调度任务的功能。原理是根据当前时间推算出最近一个星期四17:20:00的绝对时间,然后计算与当前时间的时间差,再去调用 ScheduledExceutor 函数的参数。

计算最近时间用到 java.util.calendar 的功能。先解释一下calendar的一些设计思想。Calendar有以下几种唯一标识一个日期的组合方式:

 YEAR + MONTH + DAY_OF_MONTH 
 YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK 
 YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK 
 YEAR + DAY_OF_YEAR 
 YEAR + DAY_OF_WEEK + WEEK_OF_YEAR

上述组合分别加上 HOUR_OF_DAY + MINUTE + SECOND 即为一个完整的时间标识。上面的例子是采用最后一种组合方式。

可以看出,用以上的这个方法实现该任务调度还是比较麻烦的,这就需要一个更加完善的任务调度框架来解决这些复杂的调度问题。幸运的是,开源工具包 Quartz 与 JCronTab 提供了这方面强大的支持。

 

4.Quartz

 Quartz jar下载地址:http://pan.baidu.com/s/1o6pvDTS 

Quartz 可以满足更多更复杂的调度需求,首先让我们看以下实例:

java中任务调度java.util.Timer,ScheduledExecutor,Quartz的机制说明和demo代码实例分享

以上非常简洁地实现了任务调度。Quartz 设计的核心类包括 Scheduler, Job 以及 Trigger。其中,Job 负责定义需要执行的任务,Trigger 负责设置调度策略,Scheduler 将二者组装在一起,并触发任务开始执行。

好了,先就介绍以上几种吧 Quartz的其他配置以及和JCronTab另外找个时间分享吧。希望给有需要的牛牛们提供一些帮助!

 

 

 

 


最代码官方编辑于2014-3-20 18:32:16

打赏

文件名:testScheduler.rar,文件大小:9.633K 下载
最代码最近下载分享源代码列表最近下载
123456qqwqa  LV11 2019年7月16日
kk268137  LV9 2019年3月25日
四季镇  LV9 2018年9月4日
元芳你怎么看  LV15 2018年5月29日
wwwdawn  LV14 2018年5月23日
gaoshuangwen  LV2 2017年12月20日
wang1991987  LV2 2017年11月23日
xiangge  LV1 2017年10月17日
hujialuo  LV3 2017年8月28日
18202838208  LV14 2017年8月7日
最代码最近浏览分享源代码列表最近浏览
sjwc88  LV3 2024年12月13日
Oxygeni  LV6 2023年4月29日
cx330a  LV2 2023年4月26日
林间听风  LV10 2022年8月16日
随缘而遇  LV2 2021年6月16日
sangyy  LV10 2020年11月5日
trstrs  LV1 2020年10月22日
jackychen1012  LV2 2020年9月23日
kenhomeliu  LV29 2020年6月19日
912299793  LV21 2020年5月8日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友