Timer的schedule和scheduleAtFixedRate方法的区别



(一)在设定时间后执行代码的情况


(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中任务执行的时间可能会和固定频率执行的重叠,需要考虑线程的同步。







  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值