网站首页 > java教程 正文
Java实现定时器(Timer)
绪
在应用开发中,经常需要一些周期性的操作,比如每5分钟执行某一操作等。对于这样的操作最方便、高效的实现方式就是使用java.util.Timer工具类。java.util这个包中可以找到Timer和TimerTask这两个类。Timer直接从Object继承,它相当于一个计时器,能够用它来指定某个时间来执行一项任务,或者每隔一定时间间隔反复执行同一个任务。创建一个Timer后,就会生成一个线程在背后运行,来控制任务的执行。而TimerTask就是用来实现某项任务的类,它实现了Runnable接口,因此相当于一个线程。
第一步:编写测试类,该类extends TimerTask,重新run()方法,run方法里面就是你要执行的逻辑代码,示例如下:
[java] view plain copy print?
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimerTask;
publicclass MyTest1 extends TimerTask {
private SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
@Override
publicvoid run() {
System.out.println("现在时间是:"+sf.format(new Date()));
}
}
第二步:编写一个类,该类实现ServletContextListener接口
[java] view plain copy print?
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
publicclass TimerTaskManager implements ServletContextListener {
private Timer timer;
@Override
publicvoid contextInitialized(ServletContextEvent sce) {
System.out.println("程序定时执行任务.....................................");
MyTest1 t=new MyTest1();
timer=new Timer("开始执行任务",true);
/* 执行MyTest1中的run方法,t代表TimerTask的子类,0代表延迟0毫秒执行run方 * 法,1000表示每隔一秒执行一次run方法,后面两个参数可根据自己的需求而定义
*/
timer.schedule(t, 0, 1000);
}
@Override
publicvoid contextDestroyed(ServletContextEvent sce) {
System.out.println("程序定时执行任务结束.....................................");
timer.cancel();
}
}
第三步:在web.xml中添加如下代码里面填写TimerTaskManager的路径,程序在web容器启动后会初始化加载TimerTaskManager的contextInitialized方法。
监听器添加方式:
加listener标签,listener里面加listener-class标签,listener-class标签里面内容为TimerTaskManager的路径,如:com.TimerTaskManager.
举例:
[html] view plain copy print?
<listener>
<listener-class>weiming.lmapp.timer.SysContextListener</listener-class>
</listener>
相关注意点分析:
1、任务调度要优先考虑实时保证
由于Java的天性,并且在开发JDK的过程中要考虑到不同平台,而不同平台的线程调度机制是不同的,因此各种平台下JVM 的线程调度机制也是不一致的。从而Timer不能保证任务在所指定的时间内执行。另外由于TimerTask是实现Runnable接口的,在TimerTask被放进线程队列睡眠一段时间(wait)之后,当到了指定的该唤起该TimerTask时,由于执行的确切时机取决于JVM的调度策略和当前还有多少线程在等待CPU处理。因此就不能保证任务在所指定的时间内执行。通常在如下两种情况下导致任务延迟执行:
(1)有大量线程在等待执行
(2)GC机制的影响导致延迟
这也是为什么在Timer API中存在两组调度方法的原因。即:
(1)schedule()
用固定延迟调度。使用本方法时,在任务执行中的每一个延迟会传播到后续的任务的执行。
(2)、scheduleAsFixedRate()
用固定比率调度。使用本方法时,所有后续执行根据初始执行的时间进行调度,从而希望减小延迟。
具体使用哪一个方法取决于哪些参数对你的程序或系统更重要。
2、每个Timer对象要在后台启动一个线程。这种性质在一些托管的环境下不推荐使用,比如在应用服务器中。因为这些线程不在容器的控制范围之内了。
猜你喜欢
- 2024-09-09 Java 定时器、加密、File类(java定时器时间格式)
- 2024-09-09 100个Java工具类之67:定时执行Timer
- 2024-09-09 JAVA定时器的嵌套实现(java的定时器能不能提供实时保证 可能提前也可能推迟)
- 2024-09-09 Java中分布式定时器实现和原理介绍
- 2024-09-09 Java定时任务——SpringTask(java定时任务的实现方式)
- 2024-09-09 全面了解Java Timer定时器类(java定时器怎么用)
- 2024-09-09 Java多线程19:定时器Timer(java多线程实现方式)
- 2024-09-09 Java中的定时器:java.util.Timer(java中的定时器有哪些)
- 2024-09-09 Java 中如何实现定时任务(java定时任务底层原理)
- 2024-09-09 Java定时任务的五种创建方式,你都会么?
你 发表评论:
欢迎- 05-02Go 中的 channel 与 Java BlockingQueue 的本质区别
- 05-02处理线上RabbitMQ队列阻塞(rabbitmq队列状态)
- 05-02实现延迟队列,这些你知道吗?(延迟队列 kafka)
- 05-02学无止境:AQS阻塞队列和条件队列是如何使用的?
- 05-02京东大佬问我,SpringBoot中如何做延迟队列?单机与分布式如何做?
- 05-02阻塞队列ArrayBlockingQueue的实现原理浅析
- 05-02高性能队列:Java Concurrent包中的BlockingQueue
- 05-02不允许还有Java程序员不了解BlockingQueue阻塞队列的实现原理
- 最近发表
-
- Go 中的 channel 与 Java BlockingQueue 的本质区别
- 处理线上RabbitMQ队列阻塞(rabbitmq队列状态)
- 实现延迟队列,这些你知道吗?(延迟队列 kafka)
- 学无止境:AQS阻塞队列和条件队列是如何使用的?
- 京东大佬问我,SpringBoot中如何做延迟队列?单机与分布式如何做?
- 阻塞队列ArrayBlockingQueue的实现原理浅析
- 高性能队列:Java Concurrent包中的BlockingQueue
- 不允许还有Java程序员不了解BlockingQueue阻塞队列的实现原理
- JAVA并发之BlockingQueue(阻塞队列)
- dify案例分享-API文档生成接口代码
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)