衆所周知,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作一個定時任務,變得簡單明瞭。