为什么我能够简简单单的用三步就能实现Java定时器(Timer)?

为什么我能够简简单单的用三步就能实现Java定时器(Timer)?在应用开发中,经常需要一些周期性的操作,比如每5分钟执行某一操作等。对于这样的操作最方便、高效的实现方式就是使用java.util.Timer工

欢迎大家来到IT世界,在知识的湖畔探索吧!

Java实现定时器(Timer)

在应用开发中,经常需要一些周期性的操作,比如每5分钟执行某一操作等。对于这样的操作最方便、高效的实现方式就是使用java.util.Timer工具类。java.util这个包中可以找到Timer和TimerTask这两个类。Timer直接从Object继承,它相当于一个计时器,能够用它来指定某个时间来执行一项任务,或者每隔一定时间间隔反复执行同一个任务。创建一个Timer后,就会生成一个线程在背后运行,来控制任务的执行。而TimerTask就是用来实现某项任务的类,它实现了Runnable接口,因此相当于一个线程。

为什么我能够简简单单的用三步就能实现Java定时器(Timer)?

第一步:编写测试类,该类extends TimerTask,重新run()方法,run方法里面就是你要执行的逻辑代码,示例如下:

[java] view plain copy print?

  1. import java.text.SimpleDateFormat;

  2. import java.util.Date;

  3. import java.util.TimerTask;

  4. publicclass MyTest1 extends TimerTask {

  5. private SimpleDateFormat sf=new SimpleDateFormat(“yyyy-MM-dd hh:mm:ss”);

  6. @Override

  7. publicvoid run() {

  8. System.out.println(“现在时间是:”+sf.format(new Date()));

  9. }

  10. }

第二步:编写一个类,该类实现ServletContextListener接口

[java] view plain copy print?

  1. import javax.servlet.ServletContextEvent;

  2. import javax.servlet.ServletContextListener;

  3. publicclass TimerTaskManager implements ServletContextListener {

  4. private Timer timer;

  5. @Override

  6. publicvoid contextInitialized(ServletContextEvent sce) {

  7. System.out.println(“程序定时执行任务……………………………….”);

  8. MyTest1 t=new MyTest1();

  9. timer=new Timer(“开始执行任务”,true);

  10. /* 执行MyTest1中的run方法,t代表TimerTask的子类,0代表延迟0毫秒执行run方 * 法,1000表示每隔一秒执行一次run方法,后面两个参数可根据自己的需求而定义

  11. */

  12. timer.schedule(t, 0, 1000);

  13. }

  14. @Override

  15. publicvoid contextDestroyed(ServletContextEvent sce) {

  16. System.out.println(“程序定时执行任务结束……………………………….”);

  17. timer.cancel();

  18. }

  19. }

第三步:在web.xml中添加如下代码里面填写TimerTaskManager的路径,程序在web容器启动后会初始化加载TimerTaskManager的contextInitialized方法。

监听器添加方式:

加listener标签,listener里面加listener-class标签,listener-class标签里面内容为TimerTaskManager的路径,如:com.TimerTaskManager.

举例:

[html] view plain copy print?

  1. <listener>

  2. <listener-class>weiming.lmapp.timer.SysContextListener</listener-class>

  3. </listener>

相关注意点分析:

1、任务调度要优先考虑实时保证

由于Java的天性,并且在开发JDK的过程中要考虑到不同平台,而不同平台的线程调度机制是不同的,因此各种平台下JVM 的线程调度机制也是不一致的。从而Timer不能保证任务在所指定的时间内执行。另外由于TimerTask是实现Runnable接口的,在TimerTask被放进线程队列睡眠一段时间(wait)之后,当到了指定的该唤起该TimerTask时,由于执行的确切时机取决于JVM的调度策略和当前还有多少线程在等待CPU处理。因此就不能保证任务在所指定的时间内执行。通常在如下两种情况下导致任务延迟执行:

(1)有大量线程在等待执行

(2)GC机制的影响导致延迟

这也是为什么在Timer API中存在两组调度方法的原因。即:

(1)schedule()

用固定延迟调度。使用本方法时,在任务执行中的每一个延迟会传播到后续的任务的执行。

(2)、scheduleAsFixedRate()

用固定比率调度。使用本方法时,所有后续执行根据初始执行的时间进行调度,从而希望减小延迟。

具体使用哪一个方法取决于哪些参数对你的程序或系统更重要。

2、每个Timer对象要在后台启动一个线程。这种性质在一些托管的环境下不推荐使用,比如在应用服务器中。因为这些线程不在容器的控制范围之内了。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/22216.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信