`
javaeye_hua
  • 浏览: 78808 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java 实现调度器

阅读更多
public class TimerTest implements TaskInter{

	
	/**调度任务**/
	@Override
	public void work() {
		// TODO Auto-generated method stub
		System.out.println("timer tast start work ...");
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		TimerTest test = new TimerTest();//调度任务实现类
		Date dt = new Date();//调度开始时间
		TimerTaskImpl task = new TimerTaskImpl(dt,Calendar.SECOND,5,test);//表示每隔5s执行一次
		TimerDispatcher dispatcher = new TimerDispatcher(dt,task);
		dispatcher.startDispatcher();
	}

}

拷贝附件timer.jar到lib目录,按照上述测试即可实现。 

2009-10-13 update:

最近测试发现,上次timer.jar有一个bug,在起始调度时间在当前时间之前时,会自动调用。

今天新发布的timer.jar,实现了首次调度时间为调度周期在当前时间之后(当前时间)时,避免上次出现的问题:

eg. 当前时间:2009-10-13 09:47:00

      调度指定时间:2009-10-13 08:47:00

      调度间隔:4h

首次调用时间为:2009-10-13 12:47:00,而不是在系统启动就首次调度。

0
0
分享到:
评论
2 楼 javaeye_hua 2011-07-18  
javalzbin 写道
感谢你的demo,呵呵,没看你的demo我都不知道什么叫调度器
不过我看了一下,我发现了一个问题,想问一下
/*****local task***********/
String dt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
String lt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(System.currentTimeMillis()));
if(this.task != null && dt.compareTo(lt) >= 0){
task.work();//调度工作
}
/******start next dispatcher*********/
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(calendarTime, interval);
TimerDispatcher dispatcher = new TimerDispatcher(calendar.getTime(),new TimerTaskImpl(calendar.getTime(),calendarTime,interval,task));
dispatcher.startDispatcher();
/****close local dispatcher***********/
this.timerCancel();

---------------------------------------------------------------------
this.timerCancel();

问题在这里,在你的demo中,每一次调度,你会把当前的Timer给取消,然后执行下次调度时,又会重新创建一个对象,其实我的想法是,这个Timer对象是不是可以共用。
即,首先,创建一个单例类,继承Timer,当服务启动时,只会创建一个Timer对象,那么,在这里:
public void startDispatcher(){
Timer timer = new Timer();
task.timer = timer;
timer.schedule(task, date);
}
---------------------------------------
Timer timer 的创建就由单例类来提供对象,即
Timer timer = Singleton.getInstance();
这样一来,只会有一个timer对象。
而在:
----------------------------------------------------------
/*****local task***********/
String dt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
String lt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(System.currentTimeMillis()));
if(this.task != null && dt.compareTo(lt) >= 0){
task.work();//调度工作
}
/******start next dispatcher*********/
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(calendarTime, interval);
TimerDispatcher dispatcher = new TimerDispatcher(calendar.getTime(),new TimerTaskImpl(calendar.getTime(),calendarTime,interval,task));
dispatcher.startDispatcher();
/****close local dispatcher***********/
this.timerCancel();
-------------------------------------------------------这里,
将不在执行 this.timerCancel();这行代码,这样就可以达到共享一个Timer实例

其实这个问题是我今天把这个调度器集成到我的web项目的时候发现的,我添加了一个ServletContextListener,把Timer对象声明成全局变量,在初始化的方法中contextInitialized创建Timer对象,这样,在我tomcat启动时,就会启动调度器服务,然后我想在我web服务停止时,会调用销毁的
contextDestroyed方法,在这个方法里面,调用timer.cancel(),结果发现,tomcat停止了,调度器服务依然还在执行,此时我发现,然后我在销毁方法contextDestroyed中拿到的timer对象,不是当前调度器使用的Timer对象,所以没法使用 timer.cancel()方法,拿到的时候已经在this.timerCancel()终止过的对象,这种情况,除非在整个服务当中,共享一个Timer对象,要不然在销毁的contextDestroyed方法中没办法终止调度器,而且,把Timer创建成共享对象,这样也避免了对象的频繁创建,对象的创建其实还是很耗时的

这就是我通过你提供的demo发现的一个小问题,不知道我的想法对不对



谢谢你的关注。
当时制作这个是有一个比较着急的模块需要一个定时触发工作的触发器,临时写的,很不完善。您提的建议非常好,我已经进行了重构。
希望以后多多交流。
/握手
1 楼 javalzbin 2011-07-14  
感谢你的demo,呵呵,没看你的demo我都不知道什么叫调度器
不过我看了一下,我发现了一个问题,想问一下
/*****local task***********/
String dt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
String lt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(System.currentTimeMillis()));
if(this.task != null && dt.compareTo(lt) >= 0){
task.work();//调度工作
}
/******start next dispatcher*********/
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(calendarTime, interval);
TimerDispatcher dispatcher = new TimerDispatcher(calendar.getTime(),new TimerTaskImpl(calendar.getTime(),calendarTime,interval,task));
dispatcher.startDispatcher();
/****close local dispatcher***********/
this.timerCancel();

---------------------------------------------------------------------
this.timerCancel();

问题在这里,在你的demo中,每一次调度,你会把当前的Timer给取消,然后执行下次调度时,又会重新创建一个对象,其实我的想法是,这个Timer对象是不是可以共用。
即,首先,创建一个单例类,继承Timer,当服务启动时,只会创建一个Timer对象,那么,在这里:
public void startDispatcher(){
Timer timer = new Timer();
task.timer = timer;
timer.schedule(task, date);
}
---------------------------------------
Timer timer 的创建就由单例类来提供对象,即
Timer timer = Singleton.getInstance();
这样一来,只会有一个timer对象。
而在:
----------------------------------------------------------
/*****local task***********/
String dt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
String lt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(System.currentTimeMillis()));
if(this.task != null && dt.compareTo(lt) >= 0){
task.work();//调度工作
}
/******start next dispatcher*********/
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(calendarTime, interval);
TimerDispatcher dispatcher = new TimerDispatcher(calendar.getTime(),new TimerTaskImpl(calendar.getTime(),calendarTime,interval,task));
dispatcher.startDispatcher();
/****close local dispatcher***********/
this.timerCancel();
-------------------------------------------------------这里,
将不在执行 this.timerCancel();这行代码,这样就可以达到共享一个Timer实例

其实这个问题是我今天把这个调度器集成到我的web项目的时候发现的,我添加了一个ServletContextListener,把Timer对象声明成全局变量,在初始化的方法中contextInitialized创建Timer对象,这样,在我tomcat启动时,就会启动调度器服务,然后我想在我web服务停止时,会调用销毁的
contextDestroyed方法,在这个方法里面,调用timer.cancel(),结果发现,tomcat停止了,调度器服务依然还在执行,此时我发现,然后我在销毁方法contextDestroyed中拿到的timer对象,不是当前调度器使用的Timer对象,所以没法使用 timer.cancel()方法,拿到的时候已经在this.timerCancel()终止过的对象,这种情况,除非在整个服务当中,共享一个Timer对象,要不然在销毁的contextDestroyed方法中没办法终止调度器,而且,把Timer创建成共享对象,这样也避免了对象的频繁创建,对象的创建其实还是很耗时的

这就是我通过你提供的demo发现的一个小问题,不知道我的想法对不对

相关推荐

Global site tag (gtag.js) - Google Analytics