欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JDK中Timer定时任务

程序员文章站 2022-06-09 09:28:02
...

JDK中的定时任务主要分为如下四种:

  1. 系统启动,延迟delay秒后运行:schedule(TimerTask task,long delay)
  2. 系统启动,在指定时间运行:schedule(TimerTask task,Date date)
  3. 系统启动,延迟delay秒后运行,并每间隔period秒运行一次:schedule(TimerTask task, long delay, long period)
  4. 系统启动,在指定时间date运行后,并每间隔period秒运行一次:schedule(TimerTask task, Date date, long period)

实现定时任务的步骤如下:

  • 创建计时器Timer对象
  • 为TimerTask类自定义一个子类TimerTaskBean(TimerTask是一个抽象类,在定时任务中要用到其实例)
  • 调用Timer类的schedule方法,具体调用根据需求去选择
定义TimerTask的子类
package com.xsnd.demo;

import java.util.TimerTask;

/**
 * @author xiaoshiniudao_lq
 *
 */
public class TimerTaskBean extends TimerTask {
	
	/**
	 * 要执行的定时任务代码块
	 */
	@Override
	public void run() { 
		System.out.println(Thread.currentThread().getName() + " 运行结束");
	}
}

测试代码如下:

public class TimerDemo {
	public static void main(String[] args) throws ParseException {
		System.out.println("*****************************************************");
		//创建计时器
		Timer timer = new Timer("开始执行任务-------------------");
		//创建计时器任务(TimerTaskBean:是自定义的类,继承了TimerTask抽象类)
		TimerTask task = new TimerTaskBean();
		//调用计时器的schedule方法(时间表),此处的1000代表:在当前时间的1000毫秒之后,此线程会被唤醒
		timer.schedule(task, 5000);
		System.out.println("定时任务已启动,于5秒后执行");
		System.out.println("*****************************************************");
	}
}

运行结果如下:

JDK中Timer定时任务

至于指定时间的定时任务,以及间隔执行。代码完整如下:

package com.xsnd.demo;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

/**
 * 作用:利用JDK中原始的Timer,处理定时任务
 * 主要有如下四大方法:
 * 		系统启动后,延迟delay毫秒后,执行定时任务
 * 			schedule(TimerTask task,long delay)
 * 
 * 		系统启动后,系统时间达到(或当前时间超过)指定时间date后,执行定时任务
 * 			schedule(TimerTask task,Date date)
 * 		
 * 		系统启动后,延迟delay毫秒后,执行定时任务,并每间隔period毫秒执行
 * 			schedule(TimerTask task, long delay, long period)
 * 		
 * 		系统启动后,除了在设定的时间执行定时任务外,还会每间隔period毫秒执行
 * 			schedule(TimerTask task, Date date, long period)
 * 
 * @author xiaoshiniudao_lq
 *
 */
public class TimerDemo {
	
	public static void main(String[] args) throws ParseException {
//		执行一次();
//		执行多次();
		指定时间();
//		执行间隔();
	}
	
	/**
	 * 说明:定时任务用到了线程,调用schedule(TimerTask task,long delay)
	 * 定时任务之所以能在指定的时间点执行,是因为在指定时间唤醒了线程(任务),让其具有获取CPU片段的资格,但可能不会立即执行,其误差可忽略不计。
	 * 
	 */
	public static void 执行一次() {
		System.out.println("*****************************************************");
		//创建计时器
		Timer timer = new Timer("开始执行任务-------------------");
		//创建计时器任务(TimerTaskBean:是自定义的类,继承了TimerTask抽象类)
		TimerTask task = new TimerTaskBean();
		//调用计时器的schedule方法(时间表),此处的1000代表:在当前时间的1000毫秒之后,此线程会被唤醒
		timer.schedule(task, 5000);
		System.out.println("定时任务已启动,于5秒后执行");
		System.out.println("*****************************************************");
	}
	
	/**
	 * 说明:执行多次定时任务:是为了体现就算当时间点到达的时候,不一定先被唤醒的定时任务(或线程)就会被立即执行
	 */
	public static void 执行多次() {
		for(int i=1;i<11;i++){
			Timer timer = new Timer("任务 - "+i);
			TimerTask task = new TimerTaskBean();
			timer.schedule(task, 3000);
			System.out.println("第" + i + "次任务,已启动,于3秒后执行");
		}
		System.out.println("-------------任务启动完毕,等待执行-----------");
	}

	/**
	 * 作用:指定当前系统日期的19:06:59去执行任务,如果当前时间大于设定的时间,定时任务会被立即启动
	 * 说明:调用schedule(TimerTask task,Date date)方法,指定时间运行任务
	 * 
	 */
	public static void 指定时间() {
		Date date = 获取时间();
		if(date!=null){
			System.out.println("Date时间:"+date);
			Timer timer = new Timer("开始执行-------------------------");
			System.out.println("*****************定时器已启动*****************");
			TimerTask task = new TimerTaskBean();
			timer.schedule(task, date);
		}else{
			System.out.println("*****************定时器启动失败*****************");
		}
	}

	/**
	 * 作用:当指定时间达到后执行,并在此基础上每间隔2秒执行一次。
	 */
	public static void 执行间隔() {
		Date date = 获取时间();
		if(date!=null){
			Timer timer = new Timer("开始执行-------------------------");
			System.out.println("*****************定时器已启动*****************");
			TimerTask task = new TimerTaskBean();
			timer.schedule(task, date, 2000);
		}else{
			System.out.println("*****************定时器启动失败*****************");
		}
	}
	
	/**
	 * 作用:获取时间,或者说返回指定时间
	 * @return date 时间
	 */
	private static Date 获取时间() {
		Calendar c = Calendar.getInstance();
		int mon =  c.get(Calendar.MONTH)==12?1:c.get(Calendar.MONTH)+1;
		String stringDate = c.get(Calendar.YEAR) +"-"+ mon +"-"+ c.get(Calendar.DATE) + " ";
		stringDate = stringDate + "19:06:59";
		System.out.println("String时间 :"+stringDate);
		
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date=null;
		try {
			date = (Date) dateFormat.parse(stringDate);
		} catch (Exception e) {
			date=null;
		}
		return date;
	}
}

文中观点说明:

1.之所以说定时任务是一个线程,是因为启动Timer的时候,你就启动了一个线程。在JDK中的源码如下:

JDK中Timer定时任务

2.TimerTask为是一个抽象类,并且他还是一个线程,因为它实现了Runnable接口,源码如下:

JDK中Timer定时任务


这篇文章只是针对如何利用JDK自带Timer类处理定时任务,至于如何在Spring3.0中处理定时任务,以及如何使用任务调度框架quartz,这些会陆续发表出来。