Java Timer使用

来源:互联网 发布:淘宝做活动怎么做 编辑:程序博客网 时间:2024/06/08 00:37

原文:http://blog.csdn.net/eg366/article/details/11836017

 

Java自带的java.util.Timer类,通过调度一个java.util.TimerTask任务。这种方式可以让程序按照某一个频度执行,但不能指定时间运行。用的较少。

任务的调用通过子线程进行执行。

java.util.Timer

java.util.TimerTask


1. 调用方法

void java.util.Timer.schedule(TimerTask task, long delay):多长时间(毫秒)后执行任务

void java.util.Timer.schedule(TimerTask task, Date time):设定某个时间执行任务

void java.util.Timer.schedule(TimerTask task, long delay, long period):delay时间后开始执行任务,并每隔period时间调用任务一次。

void java.util.Timer.schedule(TimerTask task, Date firstTime, long period):第一次在指定firstTime时间点执行任务,之后每隔period时间调用任务一次。

void java.util.Timer.scheduleAtFixedRate(TimerTask task, long delay, long period):delay时间后开始执行任务,并每隔period时间调用任务一次。

void java.util.Timer.scheduleAtFixedRate(TimerTask task, long delay, long period):第一次在指定firstTime时间点执行任务,之后每隔period时间调用任务一次。

void java.util.Timer.cancel():终止该Timer

boolean java.util.TimerTask.cancel():终止该TimerTask

可以为每个Timer指定多个TimerTask

 

虽然可通过void java.util.Timer.schedule(TimerTask task, Date firstTime, long period)方法完成“例如:每天上午10点执行一次”的业务,但该实现是基于进行一天(1000 * 60 * 60 * 24毫秒)进行延迟的机制实现的,并不是指定某个具体时间进行执行的。

对于该种需求,可通过Quartz来进行实现

 

2. schedule和scheduleAtFixedRate的区别

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

比如

Timer t = new Timer();SimpleDateFormat fTime = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");Date d1 = fTime.parse("2005/12/30 14:10:00");t.scheduleAtFixedRate(new TimerTask() {public void run() {System.out.println("this is task you do6");}}, d1, 3 * 60 * 1000);

间隔时间是3分钟,指定开始时间是2005/12/30 14:10:00,如果我在14:17:00分执行这个程序,那么会立刻打印3次

this is task you do6     //14:10
this is task you do6     //14:13
this is task you do6     //14:16

并且注意,下一次执行是在14:19 而不是 14:20。就是说是从指定的开始时间开始计时,而不是从执行时间开始计时。

但是上面如果用schedule方法,间隔时间是3分钟,指定开始时间是2005/12/30 14:10:00,那么在14:17:00分执行这个程序,则立即执行程序一次。并且下一次的执行时间是 14:20,而不是从14:10开始算的周期(14:19)。

 

schedule()方法更注重保持间隔时间的稳定:保障每隔period时间可调用一次

scheduleAtFixedRate()方法更注重保持执行频率的稳定:保障多次调用的频率趋近于period时间,如果某一次调用时间大于period,下一次就会尽量小于period,以保障频率接近于period

 

3. 示例

3.1. 第一种方法:设定多长时间(毫秒)后执行任务

/** * 第一种方法:设定多长时间(毫秒)后执行任务 */public static void timer1() {Timer timer = new Timer();/* void java.util.Timer.schedule(TimerTask task, long delay) */timer.schedule(new TimerTask() {public void run() {System.out.println("-------任务执行--------");}}, 2000);// delay=2000毫秒 后执行该任务}

3.2. 第二种方法:设定某个时间执行任务 

/** * 第二种方法:设定某个时间执行任务 */public static void timer2() {Calendar calendar = new GregorianCalendar();calendar.add(Calendar.MINUTE, 1);calendar.set(Calendar.SECOND, 0); // 一分钟后执行Timer timer = new Timer();/* void java.util.Timer.schedule(TimerTask task, Date time) */timer.schedule(new TimerTask() {@Overridepublic void run() {System.out.println("-------任务执行--------");}}, calendar.getTime());}

3.3. 第三种方法:设定指定任务task在指定延迟delay后进行固定延迟peroid的执行

/**  * 第三种方法:设定指定任务task在指定延迟delay后进行固定延迟peroid的执行  */  public static void timer3() {    Timer timer = new Timer();      /* void java.util.Timer.schedule(TimerTask task, long delay, long period) */         timer.schedule(new TimerTask() {        public void run() {            /* 子线程进行任务的执行 */            System.out.println("-------设定要指定任务--------");        }    }, 1000, 1000);}

3.3.1. 测试第三种方法

/** * 固定延迟peroid时间后执行;peroid时间不是以任务执行完的时间为计算起点(某次任务执行完成后,经过peroid时间后再次调用[不是这样的] * )。 而是每隔peroid时间调用任务一次。当任务执行的时间小于peroid时间,可以保证每隔peroid时间调用一次。 * 当任务的执行时间大于peroid时间时,从现象上看:任务一执行完,就会立刻进入下一次任务的执行 */public static void timer3a() {Timer timer = new Timer();final StopWatch watch = new StopWatch();watch.start();timer.schedule(new TimerTask() {Integer i = 1;public void run() {System.out.println(watch.getTime());System.out.println("########第" + i + "次执行开始########");try {Thread.sleep(400);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("########第" + i + "次执行结束########");i++;watch.reset();watch.start();}}, 1000, 500);}

period:500毫秒;每次任务执行时间400毫秒;所以每次任务执行完成后到下一次任务调用开始的时间趋近于100毫秒

打印日志信息:

1000  ########第1次执行开始########  ########第1次执行结束########  109  ########第2次执行开始########  ########第2次执行结束########  93  ########第3次执行开始########  ########第3次执行结束########  93  ########第4次执行开始########  ########第4次执行结束########  93  ########第5次执行开始########  ########第5次执行结束########  93  ########第6次执行开始########  ########第6次执行结束########  93  ########第7次执行开始########  ########第7次执行结束########  93  ########第8次执行开始######## 

当将Thread.sleep(400);修改为Thread.sleep(600)时: 

打印日志信息:

1000  ########第1次执行开始########  ########第1次执行结束########  0  ########第2次执行开始########  ########第2次执行结束########  0  ########第3次执行开始########  ########第3次执行结束########  0  ########第4次执行开始########  ########第4次执行结束########  0  ########第5次执行开始########  

3.4. 第四种方法:安排指定的任务task在指定的时间firstTime开始进行重复的固定速率period执行 每天中午12点都执行一次

/** * 第四种方法:安排指定的任务task在指定的时间firstTime开始进行重复的固定速率period执行 每天中午12点都执行一次 */public static void timer4() {Calendar calendar = Calendar.getInstance();calendar.set(Calendar.HOUR_OF_DAY, 12); // 控制时calendar.set(Calendar.MINUTE, 0); // 控制分calendar.set(Calendar.SECOND, 0); // 控制秒Date time = calendar.getTime(); // 得出执行任务的时间,此处为今天的12:00:00Timer timer = new Timer();/* * void java.util.Timer.schedule(TimerTask task, Date firstTime, long * period) */timer.schedule(new TimerTask() {public void run() {System.out.println("-------设定要指定任务--------");}}, time, 1000 * 60 * 60 * 24);// 这里设定将延时每天固定执行}
0 0
原创粉丝点击