Timer定时器学习,scheduleAtFixedRate与schedule的区别,以及疑问。

(41) 2024-08-21 14:01:01

Timer定时器,一般用来做延时任务或者循环定时执行的任务。

  • timer最常用的两个方法scheduleAtFixedRate与schedule。
 //schedule(TimerTask task, long delay); //延迟delay毫秒执行task timer.schedule(TimerTaskGet("1"),1000); //schedule(TimerTask task, Date time); //task在time执行 timer.schedule(TimerTaskGet("2"),new Date()); //schedule(TimerTask task, long delay, long period) ; //延迟delay毫秒后每隔period毫秒执行一次 timer.schedule(TimerTaskGet("3"),0,1000); //schedule(TimerTask task, Date firstTime, long period) ; //从firstTime开始每隔period毫秒执行一次 timer.schedule(TimerTaskGet("4"),time,1000); //scheduleAtFixedRate(TimerTask task, long delay, long period) ; //延迟delay毫秒后每隔period毫秒执行一次 timer.scheduleAtFixedRate(TimerTaskGet("5"),0,1000); //scheduleAtFixedRate(TimerTask task, Date firstTime, long period) ; //从firstTime开始每隔period毫秒执行一次 timer.scheduleAtFixedRate(TimerTaskGet("6"),time,1000);
  • 然后,scheduleAtFixedRate与schedule的区别。

        第一个区别,在定义固定时间开始执行时,如果定义的时间已经过去,及定义time变量是过去的时间,那么schedule从当前开始每隔period的时间执行,而scheduleAtFixedRate连续执行从time到现在应该执行的任务,直到当前时间再按照每隔period的时间执行。

下面测试:

        设置开始时间,延迟3秒后执行schedule

 Timer timer = new Timer(); Date time = new Date(); System.out.println("开始时间:"+time); try { Thread.sleep(3000); }catch (InterruptedException e){ } timer.schedule(TimerTaskGet("4"),time,1000);

结果如下,隔三秒后按间隔时间执行。

开始时间:Thu Sep 06 15:51:20 CST 2018
4  Thu Sep 06 15:51:23 CST 2018
4  Thu Sep 06 15:51:24 CST 2018
4  Thu Sep 06 15:51:25 CST 2018
4  Thu Sep 06 15:51:26 CST 2018
4  Thu Sep 06 15:51:27 CST 2018

 

        设置开始时间,延迟3秒后执行scheduleAtFixedRate

 Timer timer = new Timer(); Date time = new Date(); System.out.println("开始时间:"+time); try { Thread.sleep(3000); }catch (InterruptedException e){ } timer.scheduleAtFixedRate(TimerTaskGet("6"),time,1000);

结果如下,隔三秒后将之前三秒钟任务补齐,然后再按间隔时间执行任务。

开始时间:Thu Sep 06 15:57:17 CST 2018
6  Thu Sep 06 15:57:20 CST 2018
6  Thu Sep 06 15:57:20 CST 2018
6  Thu Sep 06 15:57:20 CST 2018
6  Thu Sep 06 15:57:20 CST 2018
6  Thu Sep 06 15:57:21 CST 2018
6  Thu Sep 06 15:57:22 CST 2018
6  Thu Sep 06 15:57:23 CST 2018
6  Thu Sep 06 15:57:24 CST 2018
6  Thu Sep 06 15:57:25 CST 2018

        换句话说,如果指定开始执行的时间在当前系统运行时间之前,scheduleAtFixedRate会把已经过去的时间也作为周期执行,而schedule不会把过去的时间算上。

第二个区别,从很多博主哪里看到的实例,任务时间大于间隔时间。

 timer.scheduleAtFixedRate(new TimerTask(){ public void run() { System.out.println("execute task!"+ this.scheduledExecutionTime()); System.out.println(new Date()); try { Thread.sleep(6000); } catch (InterruptedException e) { e.printStackTrace(); } } },startDate, 3 * 1000);

结果如下:

开始时间:Thu Sep 06 16:10:27 CST 2018
execute task!24
Thu Sep 06 16:10:27 CST 2018
execute task!24
Thu Sep 06 16:10:33 CST 2018
execute task!24
Thu Sep 06 16:10:39 CST 2018
execute task!24
Thu Sep 06 16:10:45 CST 2018

scheduleAtFixedRate调用时

scheduledExecutionTime()输出间隔只有3000毫秒

new Date()输出间隔为6秒

很多博主以scheduledExecutionTime()输出判断scheduleAtFixedRate方法是不管任务执行完没有,到达间隔时间就执行下一个。

schedule调用时

scheduledExecutionTime()输出间隔只有6000毫秒

new Date()输出间隔为6秒

很多博主以scheduledExecutionTime()输出判断schedule方法是执行完成后才开始判断间隔时间。

但是输出当前时间scheduleAtFixedRate与schedule是一样的,所以我怀疑scheduledExecutionTime()方法输出的应该类似于计划时间,而不是实际时间,scheduleAtFixedRate与schedule在用时上一样是任务完成后开始执行下一个任务。

求大神指教。

 

后附测试代码,比较乱。

package code; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimerTask; import java.util.Timer; /** * @Auther: Administrator * @Date: 2018/9/6 11:27 * @Description:定时器使用方式 */ public class TimerTest { public static void main(String[] args){ Timer timer = new Timer(); Timer timer2 = new Timer(); Date time = new Date(); System.out.println("开始时间:"+time); /* try { Thread.sleep(3000); }catch (InterruptedException e){ }*/ //schedule(TimerTask task, long delay);延迟delay毫秒执行task //timer.schedule(TimerTaskGet("1"),1000); //schedule(TimerTask task, Date time);task在time执行 //timer.schedule(TimerTaskGet("2"),new Date()); //schedule(TimerTask task, long delay, long period) ; //延迟delay毫秒后每隔period毫秒执行一次 //timer.schedule(TimerTaskGet("3"),0,1000); //schedule(TimerTask task, Date firstTime, long period) ; //从firstTime开始每隔period毫秒执行一次 //timer.schedule(TimerTaskGet("4"),time,1000); //scheduleAtFixedRate(TimerTask task, long delay, long period) ; //延迟delay毫秒后每隔period毫秒执行一次 //timer.scheduleAtFixedRate(TimerTaskGet("5"),0,1000); /* try { Thread.sleep(5000); timer.cancel(); }catch (InterruptedException e){ }*/ //scheduleAtFixedRate(TimerTask task, Date firstTime, long period) ; //从firstTime开始每隔period毫秒执行一次 //timer2.scheduleAtFixedRate(TimerTaskGet("6"),time,1000); /* try { Thread.sleep(5000); timer2.cancel(); }catch (InterruptedException e){ }*/ /* schedule和scheduleAtFixedRate的区别 如果指定开始执行的时间在当前系统运行时间之前, scheduleAtFixedRate会把已经过去的时间也作为周期执行,而schedule不会把过去的时间算上 scheduleAtFixedRate 效率总体上高于schedule */ Date startDate = time; //Timer timer = new Timer(); timer.scheduleAtFixedRate(new TimerTask(){ public void run() { System.out.println("execute task!"+ this.scheduledExecutionTime()); System.out.println(new Date()); try { Thread.sleep(6000); } catch (InterruptedException e) { e.printStackTrace(); } } },startDate, 3 * 1000); } //获取时间任务 每一个task只能调用一次,所以必须每次都new一个 public static TimerTask TimerTaskGet(String s){ TimerTask timerTask = new TimerTask() { @Override public void run() { /* try { Thread.sleep(3000); }catch (InterruptedException e){ }*/ System.out.println(s+" "+new Date()); } }; return timerTask; } } 

 

THE END

发表回复