众所周知,Quartz是一个开源的做业调度框架,它彻底由Java写成,并设计用于J2SE和J2EE应用中。它提供了巨大的灵 活性而不牺牲简单性。你可以用它来为执行一个做业而建立简单的或复杂的调度。如何作一个复杂的定时做业使用quartz是个不错的选择。不过,小任务就大材小用了。土豆我今天在这里讲解的就是直接使用JDK自带的Timer,TimerTask来进行简单的定时做业。java
首先,说一下哪些场合要使用到定时做业呢。好比那些要实时处理的数据,以及一些须要统计的数据,尤为是一些大的数据统计,一般的作法就是作一个定时任务,在深夜时进行查询统计,将查询的结果放到一个统计的小表中,而后将查询出的结果显示出来。这样就减轻的服务器的压力。由于白天查询大型数据的话,无疑是浪费时间,资源,并且会出现一些问题。晚上服务器的负担则相对小不少不少。服务器
好了很少说,贴代码。框架
先定义一个Servlet。由于Servlet能够在WEB启动时当即启动。仅需简单的配置便可。
ide
package com.sinoglobal.servlets; import java.io.IOException; import java.util.Calendar; import java.util.Timer; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.sinoglobal.timer.SendQueryTimer; @SuppressWarnings("serial") public class SendQueryServlet extends HttpServlet { private SendQueryTimer sendQuerytimer; private Timer timer2; public SendQueryServlet() { super(); } public void destroy() { super.destroy(); // Just puts "destroy" string in log if (timer2 != null) { timer2.cancel(); } } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } /** * Initialization of the servlet. <br> * * @throws ServletException * if an error occurs */ public void init() throws ServletException { System.out.println("查询短信初始化:"); // 定时器开关 String startTask = getInitParameter("startTask"); // 开始运行时间 Calendar calendar = Calendar.getInstance(); // 缓冲时间(分钟) Long intervalTime = Long.parseLong(getInitParameter("intervalTime")); // 启动定时器 if (startTask.equals("true")) { timer2 = new Timer(true); sendQuerytimer = new SendQueryTimer(); timer2.schedule(sendQuerytimer, calendar.getTime(), intervalTime * 1000); } } }
上面代码就是在servlet初始化时启动SendQueryTimer,使用timer的schedule来完成定时任务。在destroy中咱们能够看到timer的cancle()方法能够中止timer。最后schedule看它的英文单词就能够知道,计划,调度的意思。测试
查看JDK的源码:this
public void schedule(TimerTask task, Date firstTime, long period) { if (period <= 0) throw new IllegalArgumentException("Non-positive period."); sched(task, firstTime.getTime(), -period); }
咱们能够看到这个方法第一个参数是一个任务,第二个参数是任务做业的开始时间,第三个很显然是相隔的时间段period[即后一次任务做业距离上一次任务做业的时间 ]。它的单位是毫秒。源码中很明显说:若是小于等于0会报错。spa
下面咱们来看看WEM.XML中配置这个servlet。线程
<servlet> <servlet-name>SendSmsServlet</servlet-name> <servlet-class> com.sinoglobal.servlets.SendSmsServlet </servlet-class> </servlet> <servlet> <servlet-name>SendQueryServlet</servlet-name> <servlet-class> com.sinoglobal.servlets.SendQueryServlet </servlet-class> <init-param> <!-- // 定时器开关 --> <param-name>startTask</param-name> <param-value>true</param-value> </init-param> <init-param> <!-- // 缓冲时间 ss--> <param-name>intervalTime</param-name> <param-value>60</param-value> </init-param> <load-on-startup>10</load-on-startup> </servlet>
看这个intervalTime其它不必看了 ,大家懂的。intervalTime是配置这个period的时间段的。60就是60毫秒。若是我配置一分钟呢,那就是60*1000;设计
好,下面咱们看TimerTask中怎么具体执行一个任务呢。code
OK,接下来看这个SendQueryTimer中的代码。
package com.sinoglobal.timer; import java.util.TimerTask; import com.sinoglobal.dao.SendDao; import com.sinoglobal.service.SendService; public class SendQueryTimer extends TimerTask { private static boolean isRunning = true; @Override public void run() { if (isRunning) { new Thread(new SendService(new SendDao())).start(); } } }
SendQueryTimer
必须得继承TimerTask执行,实现它的run方法,在run方法中启动线程执行任务。
package com.sinoglobal.service; import com.sinoglobal.dao.SendDao; import com.sinoglobal.entity.Send; public class SendService implements Runnable { private SendDao sd; public SendService(SendDao sd2) { this.sd = sd2; } public SendService() { super(); } private void querySend(SendDao sdao){ //具体业务代码,查询数据 } public void run() { System.out.println("发送短信查询:"); querySend(sd); } // 测试查询的timer。 public static void main(String[] args) { SendDao sdao = new SendDao(); SendService sendservice = new SendService(sdao); sendservice.run(); } }
//在这个线程中咱们能够写上本身的业务代码,实现具体业务。固然你能够根据你的查询结果进行相应操做。
使用Timer,TimerTask作一个定时任务,变得简单明了。