任务调度框架
事件驱动调度算法
时钟驱动调度算法
程序中按照一定时间重复执行的某个操作 抽象为一个任务
很多任务 考虑并发等就需要调度
只要将任务加入到调度器就可以按照触发器规定执行
一:Quartz
1.Quartz 任务调度的核心元素是 scheduler, trigger 和 job,
其中 trigger 和 job 是任务调度的元数据,
scheduler 是实际执行调度的控制器。
- 关于调度器scheduler
由调度器工厂创建
可以通过配置文件配置调度器相关属性信息
Scheduler有两个重要组件:ThreadPool和JobStore
JobStore是来存储运行时信息的,包括Trigger,Scheduler,JobDetail,业务锁等等
注意:Job和Trigger需要存储下来才可以被使用
3.关于触发器trigger
名和组
开始时间和结束时间
SimpleTrigger的属性包括:开始时间、结束时间、重复次数以及重复的间隔
CronTirgger:Cron表达式
明确触发时机
4.关于任务Job
Job接口实现
Job&JobDetail的关系:JobDetail封装要执行的Job的Class对象和JobDataMap
明确任务内容
5.Job和trigger的对应关系
一个Job可以对应多个trigger
一个trigger只能对应一个Job
6.将任务和触发器添加到调度器
将任务添加到触发器,再将触发器加到调度器
二:Timer任务调度(java.util.Timer) ---单线程任务调度
eg:Timer timer = new Timer();
long delay1 = 1 * 1000;
long period1 = 1000;
// 从现在开始 1 秒钟之后,每隔 1 秒钟执行一次 job1
//TimerTest extends TimerTask
timer.schedule(new TimerTest("job1"), delay1, period1);
Timer 的设计核心
是一个 TaskList 和一个 TaskThread。
Timer 将接收到的任务丢到自己的 TaskList 中,
TaskList 按照 Task 的最初执行时间进行排序。
TimerThread 在创建 Timer 时会启动成为一个守护线程。
这个线程会轮询所有任务,找到一个最近要执行的任务,然后休眠,
当到达最近要执行任务的开始时间点,TimerThread 被唤醒并执行该任务。之后 TimerThread 更新最近一个要执行的任务,继续休眠。
Timer 的优点
在于简单易用,但由于所有任务都是由同一个线程来调度,
因此所有任务都是串行执行的,同一时间只能有一个任务在执行,
前一个任务的延迟或异常都将会影响到之后的任务
对于简单的基于起始时间点与时间间隔的任务调度,使用 Timer 就足够了
(没有周期参数表示执行一次)
三:ScheduledExecutor:java.util.concurrent包中---多线程任务调度
基于线程池设计的 ScheduledExecutor。
其设计思想是,每一个被调度的任务都会由线程池中一个线程去执行,
因此任务是并发执行的,相互之间不会受到干扰。需要注意的是,
只有当任务的执行时间到来时,ScheduedExecutor 才会真正启动一个线程,
其余时间 ScheduledExecutor 都是在轮询任务的状态。
【ScheduledExecutorService】 中两种最常用的调度方法
ScheduleAtFixedRate 和 ScheduleWithFixedDelay
ScheduleAtFixedRate 是基于固定时间间隔进行任务调度:
initialDelay, initialDelay+period, initialDelay+2period, …
ScheduleWithFixedDelay 取决于每次任务执行的时间长短,
是基于不固定时间间隔进行任务调度
initialDelay, initialDelay+executeTime+delay, initialDelay+2executeTime+2*delay
如果需要【同时调度多个任务】,基于线程池的 ScheduledTimer 是更为合适的选择