本文以JBOSS4.2.3GA下使用EJB3定时服务为例。
一、 简介
作为一个简单的定时器, EJB3 定时服务提供定时任务实现的 API 。
二、 使用说明
1、 注入定时服务
@Resource
private TimerService timerService;
2、 创建定时器
timerService.createTimer
(new Date(new Date().getTime()+ intervalDuration),intervalDuration, timerInfo);
/**
* Create an interval timer whose first expiration occurs at a given point in time and
* whose subsequent expirations occur after a specified interval.
*
* @param initialExpiration The point in time at which the first timer expiration must occur.
* @param intervalDuration The number of milliseconds that must elapse between timer
* expiration notifications. Expiration notifications are
* scheduled relative to the time of the first expiration. If
* expiration is delayed(e.g. due to the interleaving of other
* method calls on the bean) two or more expiration notifications
* may occur in close succession to "catch up".
* @param info Application information to be delivered along with the timer expiration
* notification. This can be null.
*
* @return The newly created Timer.
*
* @throws IllegalArgumentException If initialExpiration is null, or initialExpiration.getTime()
* is negative, or intervalDuration is negative.
* @throws IllegalStateException If this method is invoked while the instance is in
* a state that does not allow access to this method.
* @throws EJBException If this method could not complete due to a system-level failure.
**/
public Timer createTimer( Date initialExpiration, long intervalDuration, Serializable info )
throws
IllegalArgumentException,
IllegalStateException,
EJBException;
3、 使用注解标注定时任务函数
import javax.ejb.Timeout;
@Timeout
public void timerTask(Timer t)
{ ... }
4、 当定时器创建后,则定时触发定时任务
三、 注意事项
1、 只能用在无状态会话bean 中, 且一个bean 中只能对一个方法使用timeout 定时任务注解
2、 TimerService 具有持久化特性, 也就是说如果一个TimerService 已经启动, 如果服务器重新启动了, 这个TimerService 会继续执行
3、 Timer类 所在包: ${JBOSS_HOME}/ client/ jbossall-client.jar
TimerImpl类 所在包:${JBOSS_HOME}/server/default/lib/jboss.jar
TimerServiceImpl类 所在包: ${JBOSS_HOME}/server/default/lib/jboss.jar
4、 查看定时器是否已存在的方法
timerInfo: 定时器创建时的字符串参数,可用来标识定时器
Timer timer = null;
Iterator timers = timerService.getTimers().iterator();
while(timers.hasNext())//查看定时器是否已存在
{
Timer t = (Timer) timers.next();
String info = (String) t.getInfo();
if (info.equals(timerInfo))
{
timer = t;
}
}
四、 定时服务TimerService 是如何具有持久化特性的
从 org.jboss.ejb.txtimer.TimerServiceImpl 源码 createTimer 方法看到语句
persistencePolicy.insertTimer(timerId, timedObjectId, initialExpiration, intervalDuration, info);
作用是把定时器作为记录插入数据库。JBOSS 本地使用的是hsqldb 内存数据库并把数据存储于硬盘,数据文件存储在${JBOSS_HOME}/server/default/data/hypersonic/ 。JBOSS 启动的时候会重新加载定时器。
五、 清除定时器的方法
1、 程序 : 使用 Timer 类接口 cancel()
缺点:此方法不会清除定时器的持久化数据,在服务器下次启动时定时器仍会启动。
2、 程序:使用 TimerImpl 接口实现类public 方法 killTimer()
缺点 :此方法为 JBOSS 下的定时器实现,只能在 JBOSS 服务器下使用
3、 手动:直接清除数据库中的定时器持久数据
方法:
1) 编写一个 bat 批处理文件,写入以下语句:
java -cp E:\jboss-4.2.3.GA\server\default\lib\hsqldb.jar
org.hsqldb.util.DatabaseManager -url
jdbc:hsqldb:E:/jboss-4.2.3.GA/server/default/data/hypersonic/localDB
2) 执行 bat 文件,如下图,找到你的 timer ,然后执行删除语句
缺点:需要手动清理