Java Web定时器使用转载Word格式.docx
《Java Web定时器使用转载Word格式.docx》由会员分享,可在线阅读,更多相关《Java Web定时器使用转载Word格式.docx(19页珍藏版)》请在冰豆网上搜索。
privatestaticfinalintC_SCHEDULE_HOUR=15;
publicSampleTask(ServletContextcontext){
this.context=context;
publicvoidrun(){
Calendarcal=Calendar.getInstance();
if(!
isRunning){
if(C_SCHEDULE_HOUR==cal.get(Calendar.HOUR_OF_DAY)&
&
flag){
isRunning=true;
context.log("
开始执行指定任务"
//需要执行的代码
isRunning=false;
flag=false;
指定任务执行结束"
}else{
上一次任务执行还未结束"
if(C_SCHEDULE_HOUR!
=cal.get(Calendar.HOUR_OF_DAY)){
flag=true;
要使用此监听器需要在web.xml中配置,如下:
<
listener>
listener-class>
包路径.TimerListener<
/listener-class>
/listener>
这样在web工程启动时,就会自动启动此监听器.
JAVA中Timer定时器调度方法
javatimer中的时间调度方法主要有:
schedule(TimerTasktask,DatefirstTime,longperiod)
Schedulesthespecifiedtaskforrepeatedfixed-delayexecution,beginningatthespecifiedtime.
但是如果此时的firstTime小于(时间落后于)当前时间,那么
task会立即执行,在调试的时候不方便,因为程序一启动就开始执行了,或许还没有到任务的触发点。
schedule(TimerTasktask,longdelay,longperiod)
Schedulesthespecifiedtaskforrepeatedfixed-delayexecution,beginningafterthespecifieddelay.
如果采用设置delay时间的方法,则可以进行处理。
比如:
设置执行时间为每天的13:
50,如果启动的时候时间已经过了13:
35,那么应该在明天的13:
35进行执行。
此时可以这样处理:
Calendarcal=Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY,13);
cal.set(Calendar.MINUTE,35);
//cal.add(Calendar.DAY_OF_MONTH,1);
Datedate=newDate();
date=cal.getTime();
Datenow=newDate();
longinterval=date.getTime()-now.getTime();
//shouldexecinnextday
if(interval<
0){
cal.add(Calendar.DAY_OF_MONTH,1);
interval=date.getTime()-now.getTime();
}
System.out.println("
theintervaltimeis:
"
+interval);
//theexectimeintervalis2secs.
timer.schedule(echoTask,interval,2*1000);
如果delay的时间为负数,会报异常,因此,Calendar添加一天。
JAVAWEB程序中添加定时器
//这是我的定时器类,用来定时执行某段任务;
packagecom.my.time;
importjava.text.ParseException;
importjava.text.SimpleDateFormat;
importjava.util.Date;
importjava.util.Timer;
publicclassBugXmlTimer{
public
Timertimer;
publicvoidtimerStart(){
timer=newTimer();
Datedatetime=newDate();
DatemidnightDate=newDate();
SimpleDateFormatsdf1=newSimpleDateFormat("
yyyy-MM-dd"
SimpleDateFormatsdf2=newSimpleDateFormat("
yyyy-MM-ddHH:
mm:
ss"
try{
midnightDate=sdf2.parse(sdf1.format(datetime)+"
23:
00:
00"
}catch(ParseExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
longin=midnightDate.getTime()-datetime.getTime();
System.out.println("
beforetask"
//立刻执行,然后每隔30s执行一次
timer.schedule(newBugXmlTimerTask(),0,30000);
publicvoidtimerStop(){
if(timer!
=null)
timer.cancel();
publicstaticvoidmain(String[]args){
BugXmlTimermyTimer=newBugXmlTimer();
//TODOAuto-generatedmethodstub
myTimer.timerStart();
//这是执行任务的类,即每隔一段时间要做的事情在这里
importjava.util.TimerTask;
publicclassBugXmlTimerTaskextendsTimerTask{
@Override
publicvoidrun(){
System.out.print("
runtask"
//以下是出发定时操作的类,该类实现了ServletContextListener
publicclassMyTimerListenerimplementsServletContextListener{
privateBugXmlTimermytimer=newBugXmlTimer();
publicvoidcontextInitialized(ServletContextEventevent){
mytimer.timerStart();
publicvoidcontextDestroyed(ServletContextEventevent){
mytimer.timerStop();
然后在web.xml里部署一下,即可在程序启动后运行定时器了!
<
com.my.time.MyTimerListener<
Java定时器退出解决方案
项目中用到了Timer每隔一段时间进行一些操作,现在发现有时候莫名其妙地挂在这个计时器上的操作都不做了,用“JConsole”查看其中的线程以后,发现这个定时器线程也不在了(定时器创建的时候带了名字Timertimer=newTimer("
MyTimer"
),所以直接能看到),由于日志太多,之前的日志已经找不到了,所以没有办法看是否是有异常发生以及发生在哪里。
初步估计,是不是由于TimerTask中有异常抛出,如果定时器中没有处理的话,可能就会出问题。
所以看了一下java.util.Timer的代码:
1.//在TimerThread中执行任务
2.Timer.java:
101:
TimerThread
3.//TimerThread的入口
4.//这里只有一个try/finally,如果mainloop中有异常抛出的话,肯定就结束运行。
5.Timer.java:
503:
TimerThread.run()
6.//主循环体,其中只抓住了InterruptedException异常,其他的仍然往外抛。
7.Timer.java:
518:
TimerThread.mainloop()
从上面的代码可以看出,如果执行的任务中有其他任何运行时异常(RuntimeException)抛出,就必然导致定时器取消,也就是说挂在这个定时器上所有的人物都要被取消。
明白了其内部处理机制,就要将其应用于实践,看如下例子:
1.WrongTimerTask.java:
2.
3.packageorg.supermmx.example.timer;
4.
5.importjava.util.Timer;
6.importjava.util.TimerTask;
7.
8./**
9.*Wrongtimertask.
10.*
11.*@authorSuperMMX
12.*/
13.publicclassWrongTimerTaskextendsTimerTask{
14.privateintcount=0;
15.
16.publicvoidrun(){
17.System.out.println(count);
18.count++;
19.if(count==3){
20.thrownewNullPointerException("
TestException"
21.}
22.}
23.
24.publicstaticvoidmain(String[]args){
25.try{
26.WrongTimerTasktask=newWrongTimerTask();
27.Timertimer=newTimer("
TestTimer"
28.timer.scheduleAtFixedRate(task,0,1000);
29.}catch(Exceptione){
30.e.printStackTrace();
31.}
32.}
33.}
上述代码中,每隔一秒钟打印一个递增的数值,等于3的时候抛一个空指针异常,结果怎么样呢?
整个程序全部就退出了,就因为其中唯一的线程“TestTimer”退出了。
跟前面所说的问题一模一样,只不过项目中还有很多别的线程,所以主程序并未退出。
解决方法是什么呢?
其实很简单,将TimerTask中整个run()方法try起来就可以了,保证它不再往外抛异常,代码如下:
1.RightTimerTask.java:
13.publicclassRightTimerTaskextendsTimerTask{
17.try{
18.System.out.println(count);
19.count++;
20.if(count==3){
21.thrownewNullPointerException("
23.}catch(Exceptione){
24.e.printStackTrace();
25.}
26.}
27.
28.publicstaticvoidmain(String[]args){
29.try{
30.RightTimerTasktask=newRightTimerTask();
31.Timertimer=newTimer("
32.timer.scheduleAtFixedRate(task,0,1000);
33.}catch(Exceptione){
34.e.printStackTrace();
35.}
36.}
37.}
结果就是:
异常也仍然抓住了,定时器也仍然可以继续工作,达到我们本来的目的。
结论:
使用java.util.Timer时候,在java.util.TimerTask的run()方法中实现具体操作的时候,必须要抓住所有异常,尤其是RuntimeException,必须要保证不能往外抛异常,才能保证跟预想的运行情况一致。
java定时器的应用举例。
JAVA版本定时关机程序
这个程序写的很简单,前段时间一个小MM说:
从网上下载很多定时关机器都不好用,让我推荐一个。
我下载了一些,觉得是不太好。
当时也无聊就应承说我帮你写一个吧,功能很简单。
于是java版的、粗糙的连界面都没有的定时关机器问世了。
关机是利用java调用cmd来实现的,其实如果可以采用添加计划任务的方式来实现更好。
不废话,上代码
。
MyClock.java
importjava.text.DateFormat;
importjava.text.ParseException;
importjava.text.SimpleDateFormat;
importjava.util.Date;
importjava.util.Scanner;
importjava.util.Timer;
publicclassMyClock{
publicStringcheckTime()throwsParseException{
请输入您要关机的时间,格式为mmddhhmm。
例:
01271010>
>
............."
Scannersca=newScanner(System.in);
Stringtime=sca.next();
DateFormatdf=newSimpleDateFormat("
yyyyMMddHHmm"
Datedate=df.parse("
2010"
+time);
//当输入时间在此刻之前或者是输入字符数不对的时候再次提醒输入
while(date.before(newDate())||!
time.matches("
\\d{8}"
)){
date=df.parse("
时间输入错误,请重新输入正确时间!
"
time=sca.next();
return"
+time;
publicstaticvoidmain(String[]args)throwsParseException{
Timertimer=newTimer();
Datedate=null;
yyyyMMddHHmmss"
MyClockm=newMyClock();
Stringstr=m.checkTime()+"
;
date=df.parse(str);
关机时间输入成功,程序已经启动。
请勿关闭窗口。
timer.schedule(newMyTask(),date);
MyTask.java
importjava.io.*;
importjava.util.TimerTask;
publicclassMyTaskextendsTimerTask{
@Override
publicvoidrun(){
try{
Processpro=Runtime.getRuntime().exec("
cmd/ctsshutdn"
BufferedReaderbr=newBufferedReader(newInputStreamReader(pro
.getInputStream()));
Stringmsg=null;
while((msg=br.readLine())!
=null){
System.out.println(msg);
}catch(IOExceptionexception){
}
this.cancel();
System.exit(0);
java定时器
好多朋友用过Windows的任务计划,也有不少程序迷自己曾写过时钟报警、系统自动关机等趣味程序,可却很少有朋友在Web工程中实现过类似功能。
当Web工程启动时,定时器能自动开始计时,在整个Web工程的生命期里,定时器能在每晚深夜触发一次任务。
因此定时器的存放位置也值得考查,不能简单的存在于单个Servlet或JavaBean中,必须能让定时器宿主的存活期为整个Web工程生命期,在工程启动时能自动加载运行。
结合这两点,跟Servlet上下文有关的侦听器就最合适不过了,通过在工程的配置文件中加以合理配置,会在工程启动时自动运行,并在整个工程生命期中处于监听状态。
下面就Servlet侦听器结合Java定时器来讲述整个实现过程。
要运用Servlet侦听器需要实现javax.servlet.ServletContextListener接口,同时实现它的contextInit