原创

JAVA定时任务之Timer简单使用

温馨提示:
本文最后更新于 2022年11月02日,已超过 772 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我

1 Timer 使用步骤

      1  创建一个Timer对象。

       2 创建一个TimerTask对象,也就是我们需要做的事。

      3  使用Timer对象执行TimerTask任务,可以指定延时时间,执行间隔。

    TimerTask 示例代码

/**
 * 
 */
package com.hcycom.timer;

import java.util.TimerTask;

/**
 * @author Administrator
 *
 */
public class MyTimerTask extends TimerTask{
    
	private String name;

	public MyTimerTask(String name) {
	   super();
	   this.name = name;
	 }
	    	    
		/** 
	     * @discription 在此输入一句话描述作用
	     * @author lijunjie            
	     * @created 2020年10月19日 上午9:35:04           
	     * @see java.util.TimerTask#run()     
	     */  
	    
	@Override
	public void run() {
		//打印当前任务的name内容
		System.out.println("Current exec name is = "+name);
		
	}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}
   
}

   Timer 代码示例

   
	 /**     
     * @discription 在此输入一句话描述此文件的作用
     * @author lijunjie            
     * @created 2020年10月19日 上午9:43:00    
     * tags     
     * see_to_target     
     */
    
package com.hcycom.timer;

import java.util.Timer;

/**        
     * Title: MyTimer.java    
     * Description: 描述
     * @author lijunjie            
     * @created 2020年10月19日 上午9:43:00    
     */

public class MyTimer {
	
	public static void main(String[] args) {
		//1.创建一个timer 示例
		Timer timer = new Timer();
		//2.创建一个Mytimer示例
		MyTimerTask myTimerTask = new MyTimerTask("firstTask");
		//3.通过timer 定时定频率的调用timerTask 的业务逻辑
		//延迟5s 之后执行,每秒执行一次
		timer.schedule(myTimerTask, 5*1000L, 1*1000L);
	}

}

2 Timer 常用方法:

     task 需要执行的任务

     delay 延迟多久执行,单位是毫秒,必须大于等于0

    period 每次任务的执行时间间隔,单位毫秒 ,必须大于0

    schedule(TimerTask task, long delay, long period)    延迟delay毫秒后执行task任务,每隔period毫秒执行一次。注意:如果任务执行实际花费的时间大于执行时间间隔period,那么本次任务执行完毕,会立即执行下次任务,不会在等待。

   schedule(TimerTask task, Date time)   在指定的时间time 执行任务task,如果指定的时间已经过了,任务将会被立即执行,       任务只被执行一次。

  schedule(TimerTask task, Date firstTime, long period)   从firstTime时间开始执行任务,每隔period毫秒执行一次,如果             firstTime是过去的时间,那么任务将会被立即执行。

   scheduleAtFixedRate(TimerTask task, long delay, long period)  延迟delay毫秒后,开始执行任务,每隔period毫秒执行一次,如果在执行过程中因为任何原因(如垃圾回收,网络延迟,本次任务数据量大)而导致延迟,接下的两个或多个任务会连续执行,而不会等待period毫秒后执行,从长远来看是固定频率的执行。

  scheduleAtFixedRate(TimerTask task, Date firstTime,long period) 从firstTime时间开始执行任务,每隔period毫秒执行一次, 如果firstTime是过去的时间,那么任务将会被立即执行,并且会计算firstTime 到现在时间之间应该执行任务的次数,连续执行该次数后,以period 的时间间隔执行任务。如果在执行过程中因为任何原因(如垃圾回收,网络延迟,本次任务数据量大)而导致延迟,接下的两个或多个任务会连续执行,而不会等待period毫秒后执行,从长远来看是固定频率的执行。

3 schedule scheduleAtFixedRate 的区别

     实践是检验真理的唯一标志,我们写一个TimerTask,然后分别用schedule和scheduleAtFixedRate调用,观察结果。

    TimerTask 的核心代码如下,延迟1秒钟,打印一句话,第三次执行的时间,会延迟1分钟,用来模拟任务执行过程中的突发情况,导致任务执行时间变成的情况。

@Override
	public void run() {
		//打印当前任务的name内容
		num++;
		try {
			int count = 1;
			if(num == 3) {
				System.out.println("本次延迟1分钟");
				count = 60;
			}
			Thread.sleep(count*1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		String time = format.format(System.currentTimeMillis());
		System.out.println(time+" Current exec name is = "+name+"_"+num);
		
	}

1  用schedule(TimerTask task, long delay, long period) 调用

timer.schedule(myTimerTask, 5*1000L, 10*1000L);// 5秒后执行,执行时间间隔10秒

    调用结果如下:

  

   执行结果分析:第三次执行过程中,延迟了1分钟,任务所花费的时间已经大于了 执行任务的时间间隔,所有第三次任务执行                                完之后,立即执行第四次任务,之后的任务每个10秒钟执行一次。

2  用scheduleAtFixedRate(TimerTask task, long delay, long period)调用

timer.scheduleAtFixedRate(myTimerTask, 5*1000L, 10*1000L);// 5秒后执行,执行时间间隔10秒

  调用结果如下:

    执行结果分析:第三次执行过程中延迟了1分钟,1分钟正好是6个时间间隔,接下来的第4,5,6,7,8,9次任务都是连续执行的,并没有间隔10秒钟之后在执行。,之后的任务每个10秒钟执行一次。

3 用schedule(TimerTask task, Date firstTime, long period)调用

timer.schedule(myTimerTask, format.parse("2020-10-20 15:16:00"),10*1000L);

  调用结果如下:

  

执行结果分析:设置的是过去的时间,所以程序立即执行,第三次执行过程中,延迟了1分钟,任务所花费的时间已经大于了 执                           行任务的时间间隔,所有第三次任务执行完之后,立即执行第四次任务,之后的任务每个10秒钟执行一次。

4 用scheduleAtFixedRate(TimerTask task, Date firstTime,long period)调用

timer.scheduleAtFixedRate(myTimerTask, format.parse("2020-10-20 15:29:00"), 10*1000L);

调用结果如下:

执行结果分析:启动项目的时间大概是2020-10-20 15:30:03左右,而设置的firstTime是2020-10-20 15:29:00 已经是过去的时间,所以任务会立即执行,2020-10-20 15:29:00 与2020-10-20 15:30:03 相差大概60秒,是6个任务执行间隔,所以前6个任务都是连续执行的,执行完第6个任务的时间是2020-10-20 15:31:08,2020-10-20 15:29:00 与2020-10-20 15:31:08 相差大概2分钟,是12个任务执行间隔,但是目前任务只执行了6次,所以任务继续连续执行,到了2020-10-20 15:31:21 的时间,与2020-10-20 15:29:00相差141 秒,正好是14个任务执行间隔,任务也已经执行了14次,所以从第15次以后,任务将会以每10秒的间隔执行。

简单总结:

      1  用schedule  指定第一次启动时间启动,如果指定的时间为过去的某个时间点,那么任务将会被立即执行,但是不会补充执行从指定第一启动时间到现在时刻这一段时间间隔的任务。

     2  用scheduleAtFixedRate指定第一次启动时间启动,如果指定的时间为过去的某个时间点,那么任务将会被立即执行,并且会补充执行从指定第一启动时间到现在时刻这一段时间间隔的任务

     3 用schedule  以固定时间间隔执行任务,如果中间任务发生延迟,对于后面任务执行的时间间隔没有影响,仍然以固定的时间间隔执行。

    4用scheduleAtFixedRate以固定时间间隔执行任务,如果中间任务发生延迟,会自动计算延迟时间内应该执行多少次任务,后面的任务将会连续执行,直道所有“欠”的任务被执行了,后面将会以固定的时间间隔执行任务。

   大白话解释:schedule  小明以每秒1米的速度走着,突然摔了一跤,在地上爬了1分钟后,起身继续以每秒1米的速度行走。

                        scheduleAtFixedRate  老王以每秒1米的速度走着,突然摔了一跤,在地上爬了1分钟后,起身,想想不能因为摔跤影响我的行程,于是小跑了一会,将因为摔跤而影响的行程赶上后,继续以每秒1米的速度行走。

                        schedule   小明说我要从2020年10月18号开始,每天锻炼1个小时,一看日历,今天已经2020年10月20号了,于是立马锻炼了一个小时,之后每天锻炼1小时。

                       scheduleAtFixedRate 老王说我要从2020年10月18号开始,每天锻炼1个小时,一看日历,今天已经2020年10月20号了,想想,为了强壮的身体,绝不能偷懒,于是一口气连续锻炼了3个小时,将之前欠的任务都补上了,之后每天锻炼1小时。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

正文到此结束
本文目录