(一)在设定时间后执行代码的情况
(1)schedule方法:如果指定的第一次执行时间小于当前时间,随后的执行时间按照上一次实际执行完成的时间点进行计算
(2)scheduleAtFixedRate方法:如果指定的第一次执行时间小于当前时间,随后的执行时间按照上一次开始的时间点进行计算,并且为了”catch up”会多次执行任务,TimerTask中的执行体需要考虑同步
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class Test2 {
public static void main(String[] args) throws Exception {
System.out.println("-------开始定时任务--------");
timer1();
timer2();
}
public static void timer1() throws Exception {
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date startDate = dateFormatter.parse("2016/10/20 10:10:00");
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
System.out.println("-------定时任务1--------"+this.scheduledExecutionTime());
}
}, startDate, 2*60*2000);
}
public static void timer2() throws Exception {
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date startDate = dateFormatter.parse("2016/10/20 10:10:00");
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
System.out.println("-------定时任务2--------"+this.scheduledExecutionTime());
}
}, startDate, 2*60*2000);
}
}
以上代码表示在2016/10/20 10:10:00执行,以后每隔两分钟执行一次。
如果在2016/10/20 10:17:00执行代码
执行任务时间为:
-------定时任务1--------10:10:00
-------定时任务2--------10:10:00
-------定时任务2--------10:12:00
-------定时任务2--------10:14:00
-------定时任务2--------10:16:00
下次执行任务的时间为:
-------定时任务2--------10:18:00
-------定时任务1--------10:19:00
根据以上代码执行的时间可以得知:
schedule在执行代码后,执行一次定时任务,然后根据执行代码的时间,固定延迟执行。(不会按照代码中设定的时间,而是按照实际执行时间进行固定频率的执行了,。
scheduleAtFixedRate在执行代码后,会根据代码中设定的时间,固定延迟多次执行定时任务,赶上当前时间,然后固定延迟执行。
(二) 执行任务的时间大于固定延迟时间。
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class Test2 {
public static void main(String[] args) throws Exception {
System.out.println("-------开始定时任务--------");
timer1();
timer2();
}
public static void timer1() throws Exception {
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date startDate = dateFormatter.parse("2016/10/20 13:36:00");
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("-------定时任务1--------"+this.scheduledExecutionTime());
}
}, startDate, 5*1000);
}
public static void timer2() throws Exception {
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date startDate = dateFormatter.parse("2016/10/20 13:36:00");
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("-------定时任务2--------"+this.scheduledExecutionTime());
}
}, startDate, 5*1000);
}
}
以上代码为执行任务的时间为6秒,固定间隔为5秒。
执行执行时间为:
-------开始定时任务--------
-------定时任务1--------1476935580000
-------定时任务2--------1476935580000
-------定时任务2--------1476935585000
-------定时任务1--------1476935586000
-------定时任务2--------1476935590000
-------定时任务1--------1476935592000
-------定时任务2--------1476935595000
-------定时任务1--------1476935598000
-------定时任务2--------1476935600000
-------定时任务1--------1476935604000
根据以上执行时间可以得知:
任务1执行时间间隔为6秒,因此,下一次执行时间点=上一次程序执行完成的时间点+间隔时间
任务2执行时间间隔为5秒,因此,下一次执行时间点=上一次程序开始执行的时间点+间隔时间;并且 因为前一个任务需要执行6秒,但是固定间隔为5秒,当前任务已经开始执行了,因此两个任务间存在重叠,需要考虑线程同步
总结:
schedule方法,定时任务,按照代码实际执行任务的时间进行固定频率的执行,不按照原来代码中设定的时间进行固定频率执行。
scheduleAtFixedRate方法,定时任务,按照代码中指定的时间进行固定频率的执行,但是TimerTask中任务执行的时间可能会和固定频率执行的重叠,需要考虑线程的同步。
更多推荐
Timer的schedule和scheduleAtFixedRate方法的区别
发布评论