Timer的schedule和scheduleAtFixedRate方法的区别解析

本文详细解析了 Java 中 Timer 类的 schedule 和 scheduleAtFixedRate 方法的区别,通过实例演示了两种方法在不同情况下的执行行为,特别是当任务执行时间超过预定周期时的表现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在java中,Timer类主要用于定时性、周期性任务的触发,这个类中有两个方法比较难理解,那就是schedule和scheduleAtFixedRate方法,在这里就用实例分析一下。

(1)schedule方法:“fixed-delay”;如果第一次执行时间被delay了,随后的执行时间 上一次实际执行完成的时间点进行计算;

(2)scheduleAtFixedRate方法:“fixed-rate”;如果第一次执行时间被delay了,随后的执行时间按照上一次开始的时间点进行计算,并且为了”catch up”会多次执行任务,TimerTask中的执行体需要考虑同步  

SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");  
Date startDate = dateFormatter.parse("2010/11/26 00:20:00");  
Timer timer = new Timer();  
timer.scheduleAtFixedRate(new TimerTask(){  
   public void run()  
   {  
       System.out.println("execute task!" + this.scheduledExecutionTime());  
   }  
},startDate,3*60*1000);
以上的代码,表示在2010-11-26 00:20:00秒开始执行,每3分钟执行一次假设在2010/11/26 00:27:00执行,
以上会打印出3次:
execute task!   00:20 
execute task!   00:23    catch up 
execute task!   00:26    catch up
下一次执行时间是00:29,相对于00:26 当换成schedule方法时,在2010/11/26 00:27:00执行 会打印出1次  execute task!  00:20 无catch up 下一次执行时间为00:30,相对于00:27

以上考虑的都是在你设定的timer开始时间后,程序才被执行当执行任务的时间大于周期间隔时,会发生什么呢?

(1)schedule方法:下一次执行时间相对于上一次实际执行完成的时间点,因此执行时间会不断延后

(2)scheduleAtFixedRate方法:下一次执行时间相对于上一次开始的时间点,因此执行时间不会延后,存在并发性

以下例程序来测试上述结论,TimerTask需要执行6秒钟,但是间隔周期为5秒钟 

package test;  
import java.text.ParseException;  
import java.text.SimpleDateFormat;  
import java.util.Date;  
import java.util.Timer;  
import java.util.TimerTask;  
public class Test {  
      
    public static void main(String[] args) throws ParseException {  
        SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");  
        Date startDate = dateFormatter.parse("2010/11/28 01:06:00");  
        Timer timer = new Timer();  
        timer.schedule(new TimerTask(){  
           public void run() {  
               try {  
                   Thread.sleep(6000);  
               } catch (InterruptedException e) {  
                   e.printStackTrace();  
               }  
               System.out.println("execute task!"+ this.scheduledExecutionTime());  
           }  
        },startDate, 5 * 1000);  
    }  
      
}
schedule方法的执行结果如下:
execute task!1290877560001 
execute task!1290877566001 
execute task!1290877572001 
execute task!1290877578001 
execute task!1290877584001 
execute task!1290877590001 
execute task!1290877596001 
execute task!1290877602001 
execute task!1290877608001 
execute task!1290877614001 
execute task!1290877620001 
execute task!1290877626001 
execute task!1290877632001 
execute task!1290877638001
可以看出,间隔时间都为6秒,因此, 下一次的执行时间点=上一次程序执行完成的时间点+间隔时间 
当换成scheduleAtFixedRate方法的执行结果如下:
execute task!1290877860000 
execute task!1290877865000 
execute task!1290877870000 
execute task!1290877875000 
execute task!1290877880000 
execute task!1290877885000 
execute task!1290877890000 
execute task!1290877895000 
execute task!1290877900000 
execute task!1290877905000 
execute task!1290877910000 
execute task!1290877915000 
execute task!1290877920000 
execute task!1290877925000 
execute task!1290877930000
可以看出,间隔时间都为5秒,因此, 下一次的执行时间点=上一次程序开始执行的时间点+间隔时间 ;并且因为前一个任务要执行6秒,而当前任务已经开始执行了,因此两个任务间存在重叠,需要考虑线程同步。

转载于:https://my.oschina.net/psuyun/blog/140370

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值