Java定时器
开头简单介绍Timer类:java.util.Timer类提供了工具,线程调度任务在后台线程中将来执行
- 这个类是线程安全的,即多个线程可以无需进行外部同步共享单个Timer对象
- 此类安排任务执行一次,或者定期重复执行
- 所有构造函数启动一个计时器线程
定时器Java代码:
1 package com.yzj; 2 3 import java.text.SimpleDateFormat; 4 import java.util.Date; 5 import java.util.Timer; 6 7 import javax.servlet.ServletContextEvent; 8 import javax.servlet.ServletContextListener; 9 10 public class Test implements ServletContextListener 11 { 12 13 private Timer timer = null; 14 15 /** 16 * 容器初始化servlet时调用 17 */ 18 public void contextInitialized(ServletContextEvent arg0) 19 { 20 timer = new Timer(true); 21 /* 22 * scheduleAtFixedRate()方法说明: 23 * 参数1.要执行的任务 24 * 参数2.调用scheduleAtFixedRate方法后,要等待多长时间去第一次执行run() 25 * 参数3.第一次调用后,从第二次开始每隔多长时间再去调用run() 26 */ 27 timer.scheduleAtFixedRate(new TestTask(), 10 * 1000, 30 * 1000); 28 System.out.println("开始执行contextInitialized()的时间:" + Test.getNow()); 29 } 30 31 /** 32 * servlet销毁时调用 33 */ 34 public void contextDestroyed(ServletContextEvent arg0) 35 { 36 if (timer != null) 37 { 38 timer.cancel(); 39 } 40 } 41 42 public static String getNow() 43 { 44 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 45 return sdf.format(new Date()); 46 } 47 }
1 package com.yzj; 2 3 import java.util.TimerTask; 4 5 public class TestTask extends TimerTask 6 { 7 private static boolean isRunning = false; 8 9 int x = 0; 10 11 @Override 12 public void run() 13 { 14 x += 1; 15 System.out.println("第" + x + "次执行run()的时间:" + Test.getNow()); 16 if (!isRunning) 17 { 18 isRunning = true; 19 System.out.println("开始执行任务。"); 20 int i = 0; 21 while (i++ < 10) 22 { 23 System.out.println("已完成任务的" + i + "/" + 10); 24 } 25 isRunning = false; 26 System.out.println("任务执行结束。"); 27 } 28 else 29 { 30 System.out.println("上一次任务执行还未结束,本次任务不能执行。"); 31 } 32 } 33 }
web.xml配置
<listener> <listener-class>com.yzj.Test</listener-class> </listener>
上图可以看出,scheduleAtFixedRate的第二个参数和第三个参数的区别
-------------------------------------------------------------------------------------------------
最后简单说明schedule和scheduleAtFixedRate的区别:
schedule() 方法用于安排指定的任务进行重复的固定延迟执行,在指定的延迟后开始。
scheduleAtFixedRate() 方法用于安排指定的任务进行重复的固定速率执行,在指定的延迟后开始。
通俗讲就是:
schedule() 如果第一次执行时间被delay了,随后的执行时间按照上一次实际执行完成的时间点计算
scheduleAtFixedRate() 如果第一次执行时间被delay了,随后的执行时间按照上一次开始的时间点进行计算,它会为了catch up,会多次执行任务,TimerTask中的执行体需要考虑同步
当执行任务的时间大于周期间隔时,
schedule() 下一次执行的时间相对于上一次实际执行完成的时间点,因此执行时间会不断延后
scheduleAtFixedRate() 下一次执行的时间相对于上一次开始的时间点,因此执行时间不会延后,存在并发性