在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 接口。

  1. Timer类:设定定时器的参数,包括起始时间、间隔时间、时延时间,详情见schedule方法。
  2. 注意点:同一个TimerTask对象不能两次加入到Timer中执行,若你有多个任务要执行,需要声明多个TimerTask的实例。

第二个参数"0"的意思是:(0就表示无延迟)
当你调用该方法后,该方法必然会调用 TimerTask 类 TimerTask 类 中的 run() 方法,这个参数就是这两者之间时间的差值,也就是说,用户调用 schedule() 方法后,要等待这么长的时间才可以第一次执行 run() 方法。

第三个参数"60*60*1000"的意思就是:
(单位是毫秒60*60*1000为一小时)
(单位是毫秒3*60*1000为三分钟)
第一次调用之后,从第二次开始每隔多长的时间调用一次 run() 方法。

java.util.Timer类似于闹钟定时做任务的更多相关文章

  1. java.util.Timer demo good

    package timer; import java.util.Date; import java.util.Timer; import java.util.TimerTask; import org ...

  2. Java基础复习--java.util.Timer定时任务

    在java中,Timer类主要用于定时性.周期性任务 的触发,这个类中有两个方法比较难理解,那就是schedule和scheduleAtFixedRate方法,在这里就用实例分析一下. (1)sche ...

  3. 使用java.util.Timer来周期性的执行制定的任务

    使用java.util.Timer来周期性的执行制定的任务 public class HandlerTest extends Activity { int[] images = new int[] { ...

  4. 任务调度--使用java.util.Timer实现

    任务调度是指基于给定时间点,给定时间间隔或者给定执行次数自动执行任务. 举个例子,比如说我们希望一个系统每周日晚上9点都将数据库文件备份一次,这时我们就可以使用任务调度来实现.为了更加的方便,我们需要 ...

  5. java.util.Timer简介

    Timer是用于管理在后台执行的延迟任务或周期性任务,其中的任务使用java.util.TimerTask表示.任务的执行方式有两种: 按固定速率执行:即scheduleAtFixedRate的两个重 ...

  6. java.util.Timer分析源码了解原理

    Timer中最主要由三个部分组成: 任务 TimerTask .  任务队列: TaskQueue queue 和 任务调试者:TimerThread thread 他们之间的关系可以通过下面图示: ...

  7. java倒计时使用java.util.Timer实现,使用两个线程,以秒为单位

    public class Countdown3 { private int lin; private int curSec; public Countdown3(int lin)throws Inte ...

  8. Java:利用java Timer类实现定时执行任务的功能

    一.概述 在java中实现定时执行任务的功能,主要用到两个类,Timer和TimerTask类.其中Timer是用来在一个后台线程按指定的计划来执行指定的任务.TimerTask一个抽象类,它的子类代 ...

  9. Java定时任务:利用java Timer类实现定时执行任务的功能

    一.概述 在java中实现定时执行任务的功能,主要用到两个类,Timer和TimerTask类.其中Timer是用来在一个后台线程按指定的计划来执行指定的任务. TimerTask一个抽象类,它的子类 ...

随机推荐

  1. spi数据KL25用SPI操作nor flash

    最近研究spi数据,稍微总结一下,以后继续补充: KL25的SPI连接一个nor flash.该flash型号为FM25F04,支撑SPI的模式0和模式3,要求高位先发送,在上升沿采集数据. 通常,S ...

  2. Ubuntu下JDK+Tomcat+MySql环境的搭建

    主机在阿里云上,所以网络的配置都省了,只剩下软件的安装和配置 1.安装mysql 1.1 apt-get install mysql-server-5.5 安装过程中,有两次提示输入 mysql 的  ...

  3. EF框架操作postgresql,实现WKT类型坐标的插入,查询,以及判断是否相交

    1.组件配置 首先,要下载.NET for Postgresql的驱动,npgsql,EF6,以及EntityFramework6.Npgsql,版本号 3.1.1.0. 由于是mvc项目,所以,把相 ...

  4. Dell-R730 【Pxe+dhcp+ftp+tftp+Kickstart+CentOs6.6】

    IP:10.104.0.101 [root@localhost network-scripts]# cat ifcfg-em1 [root@localhost network-scripts]# ip ...

  5. 软件各种版本的含义!例如RC,M,GA等等

    RC版本   RC:(Release Candidate)   Candidate是候选人的意思,用在软件上就是候选版本.Release是发行.发布的意思.Release.Candidate.就是发行 ...

  6. 六、spark常见问题总结(转载)

    问题导读 1.当前集群的可用资源不能满足应用程序的需求,怎么解决? 2.内存里堆的东西太多了,有什么好办法吗?         1.WARN TaskSchedulerImpl: Initial jo ...

  7. 创建ListView控件

    // 创建List控件 HWND hListView = CreateWindow(WC_LISTVIEW ,/*listview 宏的名字*/ L"" ,/*窗口标题*/ WS_ ...

  8. Spark-GraphxAPI学习笔记

    图的集合视图 graph包含三个基本的类集合视图: val vertices: VertexRDD[VD] val edges: EdgeRDD[ED] val triplets: RDD[EdgeT ...

  9. lamda 表达式

    Lamda 表达式 高阶语言中的lamda表达式, 灵感来自于lamda演算.lamda演算包括一条变换规则 (变量替换) 和一条函数定义方式, 通过带入和替换, 对输入产生输出. Connect 新 ...

  10. js操作符总结

    算数操作符加法操作符(+),减法操作符(-),除法操作符(/),乘法操作符(*)还可以把多种操作组合在一起:1+4*5避免产生歧义,可以用括号把不同的操作分隔开来:1+(4*5):(1+4)*5变量可 ...