Timer

一、简介

       Timer 是一个定时器工具,用来在一个后台线程计划执行指定任务。它可以计划执行一个任务一次或反复多次。TimerTask 是一个抽象类,它的子类代表一个可以被 Timer 计划的任务。

       定时器 Timer 内部使用多线程方式处理。

二、方法介绍

2.1 schedule(TimerTask task,Date time)

        在指定的日期执行一次某一任务,试运行代码如下:

public class MyTask extends TimerTask{
	public void run(){
		System.out.println("我是需要执行的定时任务"+new Date());
	}
	public static void main(String args[]){
		System.out.println("当前时间为"+new Date());
		Calendar calendar = Calendar.getInstance();
		/*执行完当前时间之后,未来的10s执行*/
		calendar.add(Calendar.SECOND,10);
		Date date = calendar.getTime();

		MyTask task = new MyTask();
		Timer timer = new Timer();
		timer.schedule(task,date);
	}
}

       输出结果如下所示,我们发现 eclipse 的任务还未销毁,呈红色状态,因为创建一个 Timer 就是启动一个线程,这个线程不是守护线程,所以会一直运行。

        如果将 Timer 改成守护线程即:Timer timer = new Timer(true)。则打印完当前时间就停止了,不会执行 task 的任务。如果有多个 TimerTask 任务及延时测试,则以队列的方式一个一个被顺序性地执行,因为前面的任务有可能消耗的时间较长,所以执行的时间和预期的时间很可能不一致。

2.2 schedule(TimerTask task,Date firstTime,long period) 

        在指定的日期之后按指定的间隔周期,无限循环的执行某一任务,试运行代码如下:

public class MyTask extends TimerTask{
	public void run(){
		System.out.println("我是需要执行的定时任务"+new Date());
	}
	public static void main(String args[]){
		System.out.println("当前时间为"+new Date());
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.SECOND,10);//执行完当前时间之后,未来的10s执行
		Date date = calendar.getTime();

		MyTask task = new MyTask();
		Timer timer = new Timer();
		timer.schedule(task,date,4000);
	}
}

       输出结果如下:

2.3 cancel()

        将自身从任务队列中进行清除,试运行代码如下:

public class MyTask extends TimerTask{
	public void run(){
		System.out.println("我是需要执行的定时任务"+new Date());
		this.cancel();
		System.out.println("我已经移除了自己的定时任务");
	}
	public static void main(String args[]){
		System.out.println("当前时间为"+new Date());
		Calendar calendar = Calendar.getInstance();
		Date date = calendar.getTime();

		MyTask task = new MyTask();
		Timer timer = new Timer();
		timer.schedule(task,date,4000);
	}
}

       输出结果如下,我们发现:代码则只执行一次,就不在循环执行了,其他的 TimerTask 不受任何影响。

        还可以使用 cancle() 方法将任务队列中全部的任务进行清空,试运行代码如下:

public class MyTaskB extends TimerTask{
	public void run(){
		System.out.println("我是需要执行的定时任务B"+new Date());
	}
}
public class MyTaskA extends TimerTask{
	public void run(){
		System.out.println("我是需要执行的定时任务A"+new Date());
	}
	public static void main(String args[]){
		System.out.println("当前时间为"+new Date());
		Calendar calendar = Calendar.getInstance();
		Date date = calendar.getTime();

		MyTaskA taskA = new MyTaskA();
		MyTaskB taskB = new MyTaskB();
		Timer timer = new Timer();
		timer.schedule(taskA,date,4000);
		timer.schedule(taskB,date,4000);
		try {
			Thread.sleep(10000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		timer.cancel();
	}
}

       输出结果如下,我们发现程序只执行 10s 的循环任务,然后全部任务被清除,并且进程被销毁,按钮由红色变为灰色。

       注意:Timer 的 cancel() 方法有时不一定会停止计划任务,而是正常执行。因为 canel() 方法有时没有争抢到 queue 锁,则让 TimerTask 类中的任务正常执行。

2.4 schedule(TimerTask task,long delay)

        以执行此方法当前的时间为参考时间,在此时间的基础上延迟指定的毫秒数后执行一次 TimerTask 任务,试运行代码如下:

public class MyTaskA extends TimerTask{
	public void run(){
		System.out.println("我是需要执行的定时任务A"+new Date());
	}
	public static void main(String args[]){
		MyTaskA taskA = new MyTaskA();
		Timer timer = new Timer();
		System.out.println("当前时间为"+new Date());
		/*任务被延迟7s执行了*/
		timer.schedule(taskA,7000);
		
	}
}

       输出结果如下,我们发现,任务呗延迟 7s 执行了。

2.5 schedule(TimerTask task,long delay,long period) 

        以执行此方法当前的时间为参考时间,在此时间的基础上延迟指定的毫秒数后执行一次 TimerTask 任务,再以某一时间间隔无限次的执行某一任务,试运行代码如下:

public class MyTaskA extends TimerTask{
	public void run(){
		System.out.println("我是需要执行的定时任务A"+new Date());
	}
	public static void main(String args[]){
		MyTaskA taskA = new MyTaskA();
		Timer timer = new Timer();
		System.out.println("当前时间为"+new Date());
		timer.schedule(taskA,7000,1000);
	}
}

       输出结果如下,我们发现在延迟了 7s 之后,任务以 1s 为时间间隔依次执行。

2.6 scheduleAtFixedRate(TimerTask task,Date firstTime,long period) 

        此方法和 schedule() 方法都会顺序的执行,只是 scheduleAtFixedRate 具有追赶性。

       schedule() 方法情况一:MyTask 里面睡 1s,主线程 timer.schedule(task,马上,3000),没有延时,第一次马上执行,第二次粗略的认为 3s 执行一次。

public class MyTaskA extends TimerTask{
	public void run(){
		System.out.println("我是需要执行的定时任务A"+new Date());
	}
	public static void main(String args[]){
		MyTaskA taskA = new MyTaskA();
		Timer timer = new Timer();
		System.out.println("当前时间为"+new Date());
		try {
			Thread.sleep(1000);
			timer.schedule(taskA,0,3000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

       schedule() 方法情况二:MyTask 里面睡 1s,主线程 timer.schedule(task,3000,4000),没有延时,第一次延迟 3s 执行, 第二次 4s 后执行。

public class MyTaskA extends TimerTask{
	public void run(){
		System.out.println("我是需要执行的定时任务A"+new Date());
	}
	public static void main(String args[]){
		MyTaskA taskA = new MyTaskA();
		Timer timer = new Timer();
		System.out.println("当前时间为"+new Date());
		try {
			Thread.sleep(1000);
			timer.schedule(taskA,3000,4000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

       schedule() 方法情况三:MyTask 里面睡 5s,主线程 timer.schedule(task,马上,2000),有延时,第一次马上执行,第二次 5s 后执行

public class MyTaskA extends TimerTask{
	public void run(){
		System.out.println("我是需要执行的定时任务A"+new Date());
	}
	public static void main(String args[]){
		MyTaskA taskA = new MyTaskA();
		Timer timer = new Timer();
		System.out.println("当前时间为"+new Date());
		try {
			Thread.sleep(5000);
			timer.schedule(taskA,0,2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

       schedule() 方法情况四:MyTask 里面睡 5s,主线程 timer.schedule(task,3000,2000),有延时,第一次延迟 3s 执行,第二次 5s 后执行。

public class MyTaskA extends TimerTask{
	public void run(){
		System.out.println("我是需要执行的定时任务A"+new Date());
	}
	public static void main(String args[]){
		MyTaskA taskA = new MyTaskA();
		Timer timer = new Timer();
		System.out.println("当前时间为"+new Date());
		try {
			Thread.sleep(5000);
			timer.schedule(taskA,3000,2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

2.6 scheduleAtFixedRate()  

       scheduleAtFixedRate() 方法情况一:MyTask 里面睡 1s,主线程 timer.scheduleAtFixedRate(task,马上,3000),没有延时,第一次马上执行,第二次粗略的认为 3s 执行一次。

public class MyTaskA extends TimerTask{
	public void run(){
		System.out.println("我是需要执行的定时任务A"+new Date());
	}
	public static void main(String args[]){
		MyTaskA taskA = new MyTaskA();
		Timer timer = new Timer();
		System.out.println("当前时间为"+new Date());
		try {
			Thread.sleep(1000);
			timer.scheduleAtFixedRate(taskA,0,3000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

       scheduleAtFixedRate() 方法情况二:MyTask里面睡 1s,主线程 timer.scheduleAtFixedRate(task,3000,4000), 没有延时,第一次延迟 3s 执行, 第二次 4s 后执行。

public class MyTaskA extends TimerTask{
	public void run(){
		System.out.println("我是需要执行的定时任务A"+new Date());
	}
	public static void main(String args[]){
		MyTaskA taskA = new MyTaskA();
		Timer timer = new Timer();
		System.out.println("当前时间为"+new Date());
		try {
			Thread.sleep(1000);
			timer.scheduleAtFixedRate(taskA,3000,4000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

       scheduleAtFixedRate() 方法情况三:MyTask 里面睡 5s,主线程 timer.scheduleAtFixedRate(task,马上,2000),有延时,第一次马上执行,第二次 5s 后执行。

public class MyTaskA extends TimerTask{
	public void run(){
		System.out.println("我是需要执行的定时任务A"+new Date());
	}
	public static void main(String args[]){
		MyTaskA taskA = new MyTaskA();
		Timer timer = new Timer();
		System.out.println("当前时间为"+new Date());
		try {
			Thread.sleep(5000);
			timer.scheduleAtFixedRate(taskA,0,2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

       scheduleAtFixedRate() 方法情况四:MyTask 里面睡 5s,主线程 timer.scheduleAtFixedRate(task,3000,2000),有延时,第一次延迟 3s 执行,第二次 5s 后执行。

public class MyTaskA extends TimerTask{
	public void run(){
		System.out.println("我是需要执行的定时任务A"+new Date());
	}
	public static void main(String args[]){
		MyTaskA taskA = new MyTaskA();
		Timer timer = new Timer();
		System.out.println("当前时间为"+new Date());
		try {
			Thread.sleep(5000);
			timer.scheduleAtFixedRate(taskA,3000,2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

       总结:这两个方法在运行效果上没有任何区别,但是 schedule() 方法没有追赶性, scheduleAtFixedRate() 方法具有追赶性。

public class MyTask extends TimerTask{
	public void run() {
		System.out.println("begin任务,我的执行时间为"+System.currentTimeMillis());
		System.out.println("end任务,  我的执行时间为"+System.currentTimeMillis());
	}

	public static void main(String[] args) {
		MyTask myTask = new MyTask();
		System.out.println("现在执行时间为"+System.currentTimeMillis());
		Calendar c = Calendar.getInstance();
		c.set(Calendar.SECOND, c.get(Calendar.SECOND)-20);
		System.out.println("计划执行时间为"+c.getTime().getTime());
		Timer timer = new Timer();
		/*因为需要提前执行,中间有20s的时间差,如果是schelude()方法,则这时间段的任务就不执行了,直接从当前时间开始往下执行*/
		timer.schedule(myTask,c.getTime(), 1000);
		
		/*scheduleAtFixedRate方法则要追赶这20s的时间差,以当前时间执行好多次,即时间相同的任务,然后继续往下执行*/
		timer.scheduleAtFixedRate(myTask,c.getTime(), 1000);
		
	}
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

快乐的小三菊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值