目录
四、schedule和scheduleAtFixedRate的区别
一、介绍
JAVA中实现定时任务调度主要有两种方式,一种时JDK自带的Timer,一种是使用第三方Quartz。比较来说Quartz的功能更加强大,由浅入深,本篇先介绍下Timer的使用。
下面时JDK帮助文档中的介绍:
一种工具,线程用其安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。 与每个 Timer 对象相对应的是单个后台线程,用于顺序地执行所有计时器任务。计时器任务应该迅速完成。如果完成某个计时器任务的时间太长,那么它会“独占”计时器的任务执行线程。因此,这就可能延迟后续任务的执行,而这些任务就可能“堆在一起”,并且在上述不友好的任务最终完成时才能够被快速连续地执行。
二、基本使用
上段介绍所说的任务实际就是一个TimerTask对象,我们通过重写它的run()方法来定义任务的具体内容。对象创建完成后通过调用Timer的schedule()方法就能实现对任务的定时调度了,Timer提供了四种schedule()方法和两个scheduleAtFixedRate()方法来安排任务,话不多说,代码走起。
public class MyTimer {
public static void main(String[] args) {
Timer timer = new Timer();
//任务1
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Calendar calendar = Calendar.getInstance();
System.out.println("一:" + sf.format(calendar.getTime()));
}
};
//任务2
TimerTask timerTask2 = new TimerTask() {
@Override
public void run() {
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Calendar calendar = Calendar.getInstance();
System.out.println("二:" + sf.format(calendar.getTime()));
}
};
Calendar calendar = Calendar.getInstance();
System.out.println(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(calendar.getTime()));
// 安排在指定的时间执行指定的任务
// calendar.add(Calendar.SECOND,3);
timer.schedule(timerTask,calendar.getTime());
// timer.schedule(timerTask2,calendar.getTime()); //同一个Timer可以同时加入多个任务对象
// Timer timer1 = new Timer();
// timer1.schedule(timerTask,calendar.getTime()); //同一个任务对象不能加入到两个Timer中
// schedule(TimerTask task, Date firstTime, long period)
// 安排指定的任务在指定的时间开始进行重复的固定延迟执行。
timer.schedule(timerTask,calendar.getTime(),2000);
// schedule(TimerTask task, long delay)
// 安排在指定延迟后执行指定的任务。
timer.schedule(timerTask,2000);
// schedule(TimerTask task, long delay, long period)
// 安排指定的任务从指定的延迟后开始进行重复的固定延迟执行。
timer.schedule(timerTask,2000,1000);
// scheduleAtFixedRate(TimerTask task, Date firstTime, long period)
// 安排指定的任务在指定的时间开始进行重复的固定速率执行。
timer.scheduleAtFixedRate(timerTask,calendar.getTime(),2000);
// scheduleAtFixedRate(TimerTask task, long delay, long period)
// 安排指定的任务在指定的延迟后开始进行重复的固定速率执行。
timer.scheduleAtFixedRate(timerTask,1000,200);
}
上面的代码中我们定义了一个Timer对象和TimerTask对象,我们可以安排任务何时执行,执行周期是多少,通过这些方法可以实现对任务最简单的定时调度。
三、Timer和TimerTask其他方法介绍
Timer
void | cancel() 终止此计时器,丢弃所有当前已安排的任务。 |
int | purge() 从此计时器的任务队列中移除所有已取消的任务。 |
TimerTask
boolean | cancel() 取消此计时器任务。 |
long | scheduledExecutionTime() 返回此任务最近实际 执行的已安排 执行时间。 |
四、schedule和scheduleAtFixedRate的区别
从上面的代码中我们很难发现schedule和scheduleAtFixedRate在用法上的区别,帮助文档上固定延迟和固定速率的解释又很晦涩,那么它们二者有什么区别呢?下面我们从这两种情况来看
1.任务首次执行的时间早于当前时间。
使用schedule()方法:
calendar.add(Calendar.SECOND,-10);
timer.schedule(timerTask,calendar.getTime(),2000);
我们任务的计划执行时间定在了10s之前,这时我们会发现任务会立即执行一次,然后按照指定的时间间隔来执行,效果如下:
使用scheduleAtFixedRate()方法:
calendar.add(Calendar.SECOND,-10);
timer.scheduleAtFixedRate(timerTask,calendar.getTime(),2000);
同样我们把任务的计划执行的时间也定在了10s前,我们会发现任务立即执行了多次来赶上延迟时间该执行的次数,当到达条件后又会按照规定的时间间隔来执行任务,效果如下:
2.任务执行的所需时间超出了任务的执行周期间隔
首先我们在任务1的run()方法里延时3S。
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Calendar calendar = Calendar.getInstance();
System.out.println("一:安排执行的时间" + sf.format(scheduledExecutionTime()));
}
};
使用schedule()方法,执行的周期间隔为2S:
timer.schedule(timerTask,calendar.getTime(),2000);
执行效果如下:
我们会发现下次的时间相对于上一次实际执行完成的时间点,因此执行的时间被不断延后了。
使用scheduleAtFixedRate()方法,同样执行周期间隔为2S:
timer.scheduleAtFixedRate(timerTask,calendar.getTime(),2000);
执行效果如下:
我们会发现下次的时间相对于上一次开始执行的时间点,因此执行的时间不会被延后。
,洗澡水烧开了,Timer用法就总结这些了,期待Quartz的学习!!!