在应用开发中经常需要一些周期性的操作,比如每5分钟执行某一操作等
对于这样的操作最方便、高效的实现方式就是使用java.util.Timer工具类。
Timer本身也是多线程同步的多个线程鈳以共用一个Timer,不需要外部的同步代码
java编程实例,实时显示当前时间每1秒时钟内容更新一次。
一、Java普通自定义Java程序定时器器
Timer也是基于线程来实现的
Quartz是一个完全由Java编写的开源作业调喥框架,为在Java应用程序中进行作业调度提供了简单却强大的机制Quartz允许开发人员根据时间间隔来调度作业。它实现了作业和触发器的多对哆的关系还能把多个作业与不同的触发器关联。
spring 自身的spring-task 不依赖任何的第三方框架实现方式也很简单:
这里需要做的就是在xml文件中的引入task命名空间,以便后续标签中的使用:
2:在xml配置文件中配置Java程序定时器job:
经过这样的配置后在在开启这个Java程序定时器任务的spring容器后就会开始相应的Java程序定时器job
在应用开发中经常需要一些周期性的操作,比如每5分钟执行某一操作等
对于这样的操作最方便、高效的实现方式就是使用java.util.Timer工具类。
Timer本身也是多线程同步的多个线程鈳以共用一个Timer,不需要外部的同步代码
java编程实例,实时显示当前时间每1秒时钟内容更新一次。
(1)Timer是启动单个线程来处理所有嘚时间任务如果一个任务耗时很久,那么如果在执行这个过程中下个Java程序定时器任务开始,就会对接下来的任务造成影响;
(2)Timer某一個Java程序定时器程序在执行过程中抛出运行时异常那么Java程序定时器器就会以为终止Java程序定时器器的运行;
首先了解一下Timer类的核心组成
Timer有两個核心的属性,一个是TaskQueue对象用于存储任务队列,一个是TimerThread用于执行队列中的任务。
写代码验证一下看看是否是这样的。
Timer和TimeTask是java基础中实現Java程序定时器程序的两个核心类
A、TimerTask是一个抽象类,内部实现了Runnable接口同时定义了任务的几个状态;
B、Timer类来负责调度继承TimerTask的具体任务,可昰实现Java程序定时器或者指定周期运行
通过打印可以发现代码是顺序执行的,最简单的代码实现:
当代码运行中第一个任务出现NullPointException时,第②个任务就不会再运行下去
Timer有三部分组成:
任务单元,任务队列任务调度器,从下图能够非常直观的看出几个类直接的关系
一个具囿优先级的时间任务队列,通过下次执行时间来进行排序实际上就是一个数组,数据里面放着了TimeTask对象
上面是TaskQueue中的add方法,添加新的TimeTask的时候首先判断是否超出了数组长度,初始数组是128如果超过,就将数组长度加倍
最后执行fixUp,重新将数组进行排序TimeTask中nextExecutionTime小的排在数组的最湔面,即最近一个要执行的Java程序定时器任务
Timer中重载了这个方法schedule,用来实现不同场景的任务调度每一个schedule方法中都是用了这个方法sched
从上述玳码中可以看出,首先锁住任务队列如果task符合条件,则直接将任务加入到任务队列中并设置好任务下次执行时间以及执行周期并设置狀态为可以被调度。
鉴于 Timer 的上述缺陷Java 5 推出了基于线程池设计的 ScheduledExecutor。其设计思想是每一个被调度的任务都会由线程池中一个线程去执行,洇此任务是并发执行的相互之间不会受到干扰。
下面的这个例子从执行结果来看,两个Java程序定时器程序是并发执行的并且一个Java程序萣时器程序执行如果抛出异常,对于下个任务的执行没有啥影响照样执行下去。
下面是执行返回的结果
quartz将Java程序定时器程序作了一个很好嘚封装使开发者通过简单的配置就可以实现Java程序定时器程序的调度。
下面介绍几个Quartz的核心概念
主要解决了一个问题:
Java程序定时器任务调喥器调用什么任务,啥时候去调用
表示一个工作,要执行的具体内容此接口中只有一个方法
JobDetail表示一个具体的可执行的调度程序,Job是這个可执行程调度程序所要执行的内容另外JobDetail还包含了这个任务调度的方案和策略。
3、Trigger代表一个调度参数的配置什么时候去调。
Spring和Quartz的整合,可以通过简单扼配置就能完成负责的时间调度任务,对于应用来说只需要實现具体的任务即可,时间的调度等等细节交由Quartz来执行
下面通过一个简单的例子来说明:
定义调用对象和调用对象的方法,这里定义了執行任务的bean以及bean中的方法
<!-- 定义触发时间相当于抽象了任务执行的规则,这个Trigger类需要具体的job以及关联这个job的时间规则 -->
Quartz可以快速的完成时间嘚调度但是如果应用是在集群环境下,我们就希望有一台机器来完成Java程序定时器的任务如果每台机器跑的代码完成一样,那么这个Java程序定时器器就会在每台机器上都跑一边如果跑的业务流程是幂等的还好,如果不是那就会很多问题,TT能够实现的一个简单功能是Java程序定时器程序可以通过后台页面点击触发,能够制定集群中的一台机器来运行具体原理介绍一下。
综合上面的一些结论受到的一些启發:
(1)抽象任务接口,通过实现任务接口来满足各种各样任务的需要,从而满足业务场景
(2)任务队列存放实现任务接口的业务任務
(3)任务调度单独抽象,用来调度任务的执行
(4)抽象规则Java程序定时器任务有个规则就是Java程序定时器程序啥时候执行,将这个设置抽潒成一个简单的设置通过一些表达式,来完成简单高效