实现功能 web项目启动时启动监听器,触发一个定时任务来实现更新或者是扫描出发事件。
web.xml配置的监听器
<listener>
<listener-class>**.**.scheduled.ScheduledInit</listener-class>
</listener>
用到了一个配置文件,里边写了定时器执行的一些属性
# To start the project delay after the execution
task.delayexec=3000
# Task interval time
task.intervalexec=3000
两个属性,一个延迟执行时间,一个执行间隔时间这里单位 毫秒
java文件 (间隔时间执行方法,执行多次)
import java.util.Properties;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class ScheduledInit implements ServletContextListener {
private static transient final Log log = LogFactory
.getLog(ScheduledInit.class);
/**
* 定时器
*/
ScheduledExecutorService singleThread = Executors
.newSingleThreadScheduledExecutor();
/**
* 在Web应用启动时初始化任务
*/
public void contextInitialized(ServletContextEvent event) {
Properties properties = new Properties();
try {
properties.load(this.getClass().getResourceAsStream(
"/updatecache.properties"));
singleThread.scheduleAtFixedRate(new UpdateTask(), Integer
.parseInt(properties.getProperty("task.delayexec")),
Integer.parseInt(properties
.getProperty("task.intervalexec")),
TimeUnit.MILLISECONDS);
} catch (Exception e) {//这个IO异常其实几乎不会发生,真的没了就是项目都不完整了~这里只是卖个萌
log.error("Error - 缓存更新配置文件:updatecache.properties 未找到");
// 定义定时器
singleThread.scheduleAtFixedRate(new UpdateTask(), 3000, 3000,
TimeUnit.MILLISECONDS);
}
}
/**
* 在Web应用结束时停止任务
*/
public void contextDestroyed(ServletContextEvent event) {
singleThread.shutdown(); // 定时器销毁
}
}
这个应该不是最常用的,常用的应该是只有延迟属性的。接下来是一个延迟执行,只执行一次的
这个地方就不上完整代码了,可以看到之前执行的是
scheduleAtFixedRate方法 <span style="white-space:pre"> </span> //<span style="font-family: Arial, Helvetica, sans-serif;">依次是要执行的线程,延迟时间,间隔时间,时间单位</span>
singleThread.schedule(new UpdateTask(), 3000,TimeUnit.MILLISECONDS);//依次是要执行的线程,延迟时间,时间单位
不知道有没有注意到我这个地方写的定时器命名前缀是single,这里意思显而易见,既然有单例就有不是单例的,非单例的定义方式不一样
ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(2); //线程池,参数为size
里边的方法执行与单例的没区别,两种定时器的区别在于第二种也就是线程池,在达到线程池上限之前,多线程同步执行,互不影响。而上边的单例则为单线程,会影响。(个人这么理解,如果有误麻烦指出谢谢~)
public class UpdateTask implements Runnable{
private static Logger log = Logger.getLogger(UpdateTask.class);
private static boolean isRunning = false;
private UpdateCacheUtil util = new UpdateCacheUtil();
/**
* 线程
*/
Date d = null;
public void run() {
if (!isRunning) {
isRunning = true;
d = new Date();
log.debug("Debug - 开始更新缓存..." + new Date()); // 开始任务
try {
util.getClass().getDeclaredMethod("Scanning")
.invoke(SpringBeanUtil.getBean("UpdateCacheUtil"));//这里是映射一个方法执行了项目在需要更新缓存的任务
} catch (Exception e) {
e.printStackTrace();
}
log.debug("Debug - 更新缓存完成,用时:"
+ (new Date().getTime() - d.getTime()) + "毫秒"); // 任务完成
isRunning = false;
} else {
log.debug("Debug - 上一次更新缓存任务执行还未结束..." + new Date()); // 上一次任务执行还未结束
}
}
}
最后附上我的 UpdateTask里边则是执行的线程具体内容,诸位各取所需吧~