Timer的schedule和scheduleAtFixedRate方法的区别

来源:互联网 发布:什么软件重装系统最好 编辑:程序博客网 时间:2024/05/16 06:28


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


(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 0