Timer的缺陷-不按定时时间执行【已入坑】

时间:2022-06-29 07:58:54

公司做项目,其中涉及到一个游戏的业务逻辑,需要使用定时类去执行,在使用Timer的时候,发现总是出现奇怪的问题。

如下代码:

package com.yifeng.test22;

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

public class RunLoter {
	private static Timer timer = new Timer();
	static public class Mytest1 extends TimerTask {

	

		@Override
		public void run() {
			// 这里不干别的只是睡觉
			try {
				System.out.println("Mytest1运行了,当前时间为" + new Date());
				Thread.sleep(20000);
				System.out.println("Mytest2运行了,当前时间为" + new Date());
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

	static public class Mytest2 extends TimerTask {

		@Override
		public void run() {
			System.out.println("Mytest2运行了,当前时间为" + new Date());
		}

	}

	public static void main(String[] args) throws ParseException {
		Mytest1 mytest1=new Mytest1();
		Mytest2 mytest2=new Mytest2();
		timer.schedule(mytest1, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-11-11 09:49:40"));
		timer.schedule(mytest2, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-11-11 09:49:40"));
		
	}
}

Timer的缺陷-不按定时时间执行【已入坑】

我去,Test2 竟然没按照时间执行,而是在test1执行结束后才去执行的。

究其原因:

这是因为Timer基本处理模型是单线程调度的任务队列模型,Timer不停地接受调度任务,所有任务接受Timer调度后加入TaskQueue,TimerThread不停地去TaskQueue中取任务来执行.此种方式的不足之处为当某个任务执行时间较长,以致于超过了TaskQueue中下一个任务开始执行的时间,会影响整个任务执行的实时性。 


你可以试用scheduleAtFixedRate方法,它会让任务尽量保证在规定的时间频率执行,如:定的时间频率是2s,因为系统繁忙,之后的2.5秒后任务才得以执行第二次,然后,Timer记下了这个延迟,并尝试在下一个任务的时候弥补这个延迟,那么,1.5秒后,任务将执行.