java.util.Timer类似于闹钟定时做任务
在web中实现任务计划,相当于实现闹钟的功能,要完成2个步骤:
1、定时器的设置;
2.对这个定时器的启动运行和停止进行实时监听
java.util.Timer定时器,实际上是个线程,定时调度所拥有的TimerTasks
一个TimerTask实际上就是一个拥有run方法的类,需要定时执行的代码放到run方法体内,TimerTask一般是以匿名类方式创建。
Timer是一种线程设施,用于安排以后在后台线程执行的任务,可安排任务执行一次,或者定期重复执行,可以看成一个定时器,可调度TimerTask,TimerTask是一个抽象类,实现了Runnable接口,所以具备多线程的能力。
Timer类使用java.util.TaskQueue在指定时间间隔添加任务,在任务时刻只能有一个线程执行TimerTask。
Timer类使用对象的wait和notify方法调度任务,Timer对象将持续将任务添加到队列,一旦有任务结束,它就会通知队列,并且另外一个线程将启动执行。
Timer是JDK中定时调度类,主要是来定时触发任务:
Timer是调度控制器,TimerTask是可调度任务
2.原理:
其基本处理模型是单线程调度的任务队列模型,Timer不停地接受调度任务,所有任务接受Timer调度后加入TaskQueue,TimerThread不停地去TaskQueue中取任务来执行.

从图上不难看出,这就是生产者--消费者模型的一种特例:多生产者,单消费者模型。
此种消息队列实现方式在浏览器中的编程模型中也有类似的实现,javascript中的定时执行函数setTimeout(expression,milliseconds)也是基于此种原理实现的。
此种方式的不足之处为当某个任务执行时间较长,以致于超过了TaskQueue中下一个任务开始执行的时间,会影响整个任务执行的实时性。为了提高实时性,可以采用多个消费者一起消费来提高处理效率,避免此类问题的实现。
Timer里面有4个schedule重载函数,而且还有两个scheduleAtFixedRate:
void scheduleAtFixedRate(TimerTask task, Date firstTime, long period)
安排指定的任务在指定的时间开始进行重复的固定速率执行。
void scheduleAtFixedRate(TimerTask task, long delay, long period)
安排指定的任务在指定的延迟后开始进行重复的固定速率执行。
使用scheduleAtFixedRate的话,Timer会尽量的让任务在一个固定的频率下运行。例如:在上面的例子中,让secondTask在1秒钟后,每3秒钟执行一次,但是因为java不是实时的,所以,我们在上个程序中表达的原义并不能够严格执行,例如有时可能资源调度紧张4秒以后才执行下一次,有时候又3.5秒执行。如果我们调用的是scheduleAtFixedRate,那么Timer会尽量让你的secondTask执行的频率保持在3秒一次。运行上面的程序,假设使用的是scheduleAtFixedRate,那么下面的场景就是可能的:1秒钟后,secondTask执行一次,因为系统繁忙,之后的3.5秒后secondTask才得以执行第二次,然后Timer记下了这个延迟,并尝试在下一个任务的时候弥补这个延迟,那么2.5秒后,secondTask将执行的三次。“以固定的频率而不是固定的延迟时间去执行一个任务”就是这个意思。
Timer终止的问题:
默认情况下,只要一个程序的timer线程在运行,那么这个程序就会保持运行。可以通过以下3种方法终止一个timer线程:
(1)调用timer的cancle方法。你可以从程序的任何地方调用此方法,甚至在一个timer task的run方法里;
(2)让timer线程成为一个daemon线程(可以在创建timer时使用new Timer(true)达到这个目地),这样当程序只有daemon线程的时候,它就会自动终止运行;
(3)调用System.exit方法,使整个程序(所有线程)终止。
TimerTask也有cancel方法。
上面所说的“只要一个程序的timer线程在运行,那么这个程序就会保持运行”。那么反过来,如果Timer里的所有TimerTask都执行完了,整个程序会退出吗,经测试答案是否定的,例如上面的测试代码,如果只加第一个TimerTask在Timer中执行:
timer.schedule(new MyTask(1), 5000);// 5秒后启动任务
那么5秒以后,其实整个程序还是没有退出,Timer会等待垃圾回收的时候被回收掉然后程序会得以退出,但是多长时间呢?在TimerTask的run函数执行完以后加上System.gc();就可以了。
代码如下:
package test;
import java.util.Timer;
import java.util.TimerTask;
public class TimerTest {
/**
* @param args
*/
public static void main(String[] args)throws java.io.IOException {
TimerTask task=new TimerTask(){
@Override
public void run() {
System.out.println("hello");
}
};
Timer timer=new Timer();
timer.schedule(task, 0,5000); //0标识要延迟的时间,5000指毫秒
}
}
是 TimerTask 类,在包:import java.util.TimerTask .使用者要继承该类,并实现 public void run() 方法,将所要运行的任务封装其run方法中。因为 TimerTask 类实现了 Runnable 接口。
- Timer类:设定定时器的参数,包括起始时间、间隔时间、时延时间,详情见schedule方法。
- 注意点:同一个TimerTask对象不能两次加入到Timer中执行,若你有多个任务要执行,需要声明多个TimerTask的实例。
第二个参数"0"的意思是:(0就表示无延迟)
当你调用该方法后,该方法必然会调用 TimerTask 类 TimerTask 类 中的 run() 方法,这个参数就是这两者之间时间的差值,也就是说,用户调用 schedule() 方法后,要等待这么长的时间才可以第一次执行 run() 方法。
第三个参数"60*60*1000"的意思就是:
(单位是毫秒60*60*1000为一小时)
(单位是毫秒3*60*1000为三分钟)
第一次调用之后,从第二次开始每隔多长的时间调用一次 run() 方法。
java.util.Timer类似于闹钟定时做任务的更多相关文章
- java.util.Timer demo good
package timer; import java.util.Date; import java.util.Timer; import java.util.TimerTask; import org ...
- Java基础复习--java.util.Timer定时任务
在java中,Timer类主要用于定时性.周期性任务 的触发,这个类中有两个方法比较难理解,那就是schedule和scheduleAtFixedRate方法,在这里就用实例分析一下. (1)sche ...
- 使用java.util.Timer来周期性的执行制定的任务
使用java.util.Timer来周期性的执行制定的任务 public class HandlerTest extends Activity { int[] images = new int[] { ...
- 任务调度--使用java.util.Timer实现
任务调度是指基于给定时间点,给定时间间隔或者给定执行次数自动执行任务. 举个例子,比如说我们希望一个系统每周日晚上9点都将数据库文件备份一次,这时我们就可以使用任务调度来实现.为了更加的方便,我们需要 ...
- java.util.Timer简介
Timer是用于管理在后台执行的延迟任务或周期性任务,其中的任务使用java.util.TimerTask表示.任务的执行方式有两种: 按固定速率执行:即scheduleAtFixedRate的两个重 ...
- java.util.Timer分析源码了解原理
Timer中最主要由三个部分组成: 任务 TimerTask . 任务队列: TaskQueue queue 和 任务调试者:TimerThread thread 他们之间的关系可以通过下面图示: ...
- java倒计时使用java.util.Timer实现,使用两个线程,以秒为单位
public class Countdown3 { private int lin; private int curSec; public Countdown3(int lin)throws Inte ...
- Java:利用java Timer类实现定时执行任务的功能
一.概述 在java中实现定时执行任务的功能,主要用到两个类,Timer和TimerTask类.其中Timer是用来在一个后台线程按指定的计划来执行指定的任务.TimerTask一个抽象类,它的子类代 ...
- Java定时任务:利用java Timer类实现定时执行任务的功能
一.概述 在java中实现定时执行任务的功能,主要用到两个类,Timer和TimerTask类.其中Timer是用来在一个后台线程按指定的计划来执行指定的任务. TimerTask一个抽象类,它的子类 ...
随机推荐
- 你不知道的Eclipse用法:使用Allocation tracker跟踪Android应用内存分配
Android Tools中的DDMS带有一个很不错的跟踪内存分配的工具Allocation tracker.通过Alloction tracker,不仅知道分配了哪类对象,还可以知道在哪个线程.哪个 ...
- autotools入门笔记(二)——创建和使用静态库、动态库
带有静态库或者动态库的工程的构建过程与上一节()只包含一个源文件的工程的构建过程是类似的.只是对于复杂的工程,如果包含多个还有源文件的目录时,需要对每个包含源文件的目录执行构建过程,另外创建和使用库文 ...
- [置顶] ROS探索总结(十一)——机器视觉
机器视觉在计算机时代已经越来越流行,摄像头价格越来越低廉,部分集成深度传感器的混合型传感器也逐渐在研究领域普及,例如微软推出的Kinect,而且与之配套的软件功能十分强大,为开发带来了极大的便利.RO ...
- mybatis里面的 #{}和${}
1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号.如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by "111&qu ...
- CSS两端对齐
前面的话 两端对齐在导航条Tab的制作中非常常用.本文将详细介绍CSS两端对齐的3种实现方式 flex 弹性盒模型flex作为强大的弹性布局方式,可以hold住大部分的布局效果,当然也包括两端 ...
- Spring MVC中的HandlerMapping与HandlerAdapter
*:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...
- 结构-行为-样式-Bootstrap笔记
1.自上而下的内容布局,中间内容可变,应该用: <div class=" container-fluid"> <div class=" row" ...
- C语言之数组
数组 数组就是在内存空间中,开辟一个大的空间,然后再将这个大的空间均的分为若干份的小空间,每个小空间用来保存一个数据. 1). 数组的专业术语: 长度:指的能存放数据的个数 下标/索引:每一个数据所在 ...
- mongo数据库时间存储的问题
题记:项目中要加的内容,可以实现对设备的预定,被某个用户预定后的设备就不能再被其他用户所使用了,用户预定的时候就需要输入预定时间,web前端用到了boostrap的date的一个插件,非常好用,接下来 ...
- [SQL基础教程] 4-4 事务
[SQL基础教程] 4 数据更新 4-4 事务 事务 需要在同一处理单元中执行的一系列更新处理的集合 创建事务 事务开始语句; DML语句1; DML语句2; . . . 事务结束语句; 事务开始语句 ...