本文转载: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):多长时间(毫秒)后执行任务
(2)void java.util.Timer.schedule(TimerTask task, Date time):设定某个时间执行任务
(3)void java.util.Timer.schedule(TimerTask task, long delay, long period):delay时间后开始执行任务,并每隔period时间调用任务一次。
(4)void java.util.Timer.schedule(TimerTask task, Date firstTime, long period):第一次在指定firstTime时间点执行任务,之后每隔period时间调用任务一次。
(5)void java.util.Timer.scheduleAtFixedRate(TimerTask task, long delay, long period):delay时间后开始执行任务,并每隔period时间调用任务一次。
(6)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来进行实现
二、方法名称schedule()和scheduleAtFixedRate()两者的区别
当需要根据period区间时间循环多次调用任务的时候,会存在两种不同的策略,两种方法提供了不同的策略。
调用方法(1)、(2)只是单次执行,不存在多次调用任务的情况,所以没有提供scheduleAtFixedRate方法的调用方式。
<1>schedule()方法更注重保持间隔时间的稳定:保障每隔period时间可调用一次
<2>scheduleAtFixedRate()方法更注重保持执行频率的稳定:保障多次调用的频率趋近于period时间,如果某一次调用时间大于period,下一次就会尽量小于period,以保障频率接近于period
三、示例
(1)
1 /** 2 * 第一种方法:设定多长时间(毫秒)后执行任务 3 */ 4 public static void timer1() { 5 final StopWatch watch = new StopWatch(); 6 watch.start(); 7 Timer timer = new Timer(); 8 /* void java.util.Timer.schedule(TimerTask task, long delay) */ 9 timer.schedule(new TimerTask() { 10 public void run() { 11 watch.stop(); 12 System.out.println("-------任务执行--------"); 13 System.out.println(watch.getTime()); 14 } 15 }, 2000);// delay=2000毫秒 后执行该任务 16 }
(2)
1 /** 2 * 第二种方法:设定某个时间执行任务 3 */ 4 public static void timer2() { 5 Calendar calendar = new GregorianCalendar(); 6 calendar.add(Calendar.MINUTE, 1); 7 calendar.set(Calendar.SECOND, 0); // 一分钟后执行 8 Timer timer = new Timer(); 9 /* void java.util.Timer.schedule(TimerTask task, Date time) */ 10 timer.schedule(new TimerTask() { 11 @Override 12 public void run() { 13 System.out.println("-------任务执行--------"); 14 } 15 }, calendar.getTime()); 16 }
(3)
1 /** 2 * 第三种方法:设定指定任务task在指定延迟delay后进行固定延迟peroid的执行 3 */ 4 public static void timer3() { 5 Timer timer = new Timer(); 6 final StopWatch watch = new StopWatch(); 7 watch.start(); 8 System.out.println(Thread.currentThread().getName()); 9 /* 10 * void java.util.Timer.schedule(TimerTask task, long delay, long 11 * period) 12 */ 13 timer.schedule(new TimerTask() { 14 public void run() { 15 /* 子线程进行任务的执行 */ 16 System.out.println(Thread.currentThread().getName()); 17 System.out.println("-------设定要指定任务--------"); 18 watch.suspend(); 19 System.out.println(watch.getTime()); 20 watch.reset(); 21 watch.start(); 22 } 23 }, 1000, 1000); 24 }
(4)
1 /** 2 * 固定延迟peroid时间后执行;peroid时间不是以任务执行完的时间为计算起点(某次任务执行完成后,经过peroid时间后再次调用[不是这样的])。 3 * 而是每隔peroid时间调用任务一次。当任务执行的时间小于peroid时间,可以保证每隔peroid时间调用一次。 4 * 当任务的执行时间大于peroid时间时,从现象上看:任务一执行完,就会立刻进入下一次任务的执行 5 */ 6 public static void timer3a() { 7 Timer timer = new Timer(); 8 final StopWatch watch = new StopWatch(); 9 watch.start(); 10 timer.schedule(new TimerTask() { 11 Integer i = 1; 12 public void run() { 13 System.out.println(watch.getTime()); 14 System.out.println("########第" + i + "次执行开始########"); 15 try { 16 Thread.sleep(400); 17 } catch (InterruptedException e) { 18 e.printStackTrace(); 19 } 20 System.out.println("########第" + i + "次执行结束########"); 21 i++; 22 watch.reset(); 23 watch.start(); 24 } 25 }, 1000, 500); 26 }
period:500毫秒;每次任务执行时间400毫秒;所以每次任务执行完成后到下一次任务调用开始的时间趋近于100毫秒
打印日志信息:
1 1000 2 ########第1次执行开始######## 3 ########第1次执行结束######## 4 109 5 ########第2次执行开始######## 6 ########第2次执行结束######## 7 93 8 ########第3次执行开始######## 9 ########第3次执行结束######## 10 93 11 ########第4次执行开始######## 12 ########第4次执行结束######## 13 93 14 ########第5次执行开始######## 15 ########第5次执行结束######## 16 93 17 ########第6次执行开始######## 18 ########第6次执行结束######## 19 93 20 ########第7次执行开始######## 21 ########第7次执行结束######## 22 93 23 ########第8次执行开始########
当将Thread.sleep(400);修改为Thread.sleep(600)时:
打印日志信息:
1 1000 2 ########第1次执行开始######## 3 ########第1次执行结束######## 4 0 5 ########第2次执行开始######## 6 ########第2次执行结束######## 7 0 8 ########第3次执行开始######## 9 ########第3次执行结束######## 10 0 11 ########第4次执行开始######## 12 ########第4次执行结束######## 13 0 14 ########第5次执行开始########
(5)
1 /** 2 * 第四种方法:安排指定的任务task在指定的时间firstTime开始进行重复的固定速率period执行 3 * 每天中午12点都执行一次 4 */ 5 public static void timer4() { 6 Calendar calendar = Calendar.getInstance(); 7 calendar.set(Calendar.HOUR_OF_DAY, 12); // 控制时 8 calendar.set(Calendar.MINUTE, 0); // 控制分 9 calendar.set(Calendar.SECOND, 0); // 控制秒 10 11 Date time = calendar.getTime(); // 得出执行任务的时间,此处为今天的12:00:00 12 13 Timer timer = new Timer(); 14 /* void java.util.Timer.schedule(TimerTask task, Date firstTime, long period) */ 15 timer.schedule(new TimerTask() { 16 public void run() { 17 System.out.println("-------设定要指定任务--------"); 18 } 19 }, time, 1000 * 60 * 60 * 24);// 这里设定将延时每天固定执行 20 }
(6)
1 /** 2 * 第五种方法:设定指定任务task在指定延迟delay后进行固定频率peroid的执行。 3 * timer.schedule和timer.scheduleAtFixedRate的区别: 4 * (1)schedule()方法更注重保持间隔时间的稳定:保障每隔period时间可调用一次 5 * (2)scheduleAtFixedRate()方法更注重保持执行频率的稳定:保障多次调用的频率趋近于period时间,如果某一次调用时间大于period,下一次就会尽量小于period,以保障频率接近于period 6 */ 7 public static void timer5() { 8 Timer timer = new Timer(); 9 /* void java.util.Timer.scheduleAtFixedRate(TimerTask task, long delay, long period) */ 10 timer.scheduleAtFixedRate(new TimerTask() { 11 public void run() { 12 System.out.println("-------设定要指定任务--------"); 13 } 14 }, 1000, 500); 15 }