分類:
版權聲明:本文為博主原創文章,未經博主允許不得轉載。
java web 項目中 簡單定時器實現 Timer
項目背景: 系統中有一個存放壓縮文件的臨時文件夾。當時間長了后 存放文件多了,占用磁盤空間過大 讓費資源, 所以需要定期去清理臨時文件夾下的文件。所以最先想到了使用定時器來實現該功能。
調查: 通過查閱資料 了解到使用java實現這個功能 有三種方法
1》使用Quartz 框架 這是一個開源的任務調度框架
2》 使用 ScheduledExecutor 實現
3》 使用 timer 實現
因為我這只是要實現一個簡單定時清理臨時文件夾的任務 不需要太多復雜的東西。 所以 我選擇了第三種方案 自己使用jdk 自帶的 timer 類來實現。
任務類 主要的業務代碼
- package com.sxl;
- import java.util.TimerTask;
- import javax.servlet.ServletContext;
- /**
- * 定時器
- * @author sxl
- *
- */
- public class DelFileTask extends TimerTask{
- private static boolean isRunning = false;
- private ServletContext context = null;
- public DelFileTask() {
- super();
- }
- public DelFileTask(ServletContext context) {
- this.context = context;
- }
- @Override
- public void run() {
- if (!isRunning) {
- context.log("開始執行指定任務");
- /**
- * 自己的業務代碼
- */
- isRunning = false;
- context.log("指定任務執行結束");
- } else {
- context.log("上一次任務執行還未結束");
- }
- }
- }
這個類 主要是繼承 TimerTask並實現它的run 方法
下面就是監聽類了 監聽服務器的啟動並將任務添加到任務棧
- package com.sxl;
- import java.util.Calendar;
- import java.util.Date;
- import javax.servlet.ServletContextEvent;
- import javax.servlet.ServletContextListener;
- public class ContextListener implements ServletContextListener{
- public ContextListener() {
- }
- private java.util.Timer timer = null;
- /**
- * 初始化定時器
- * web 程序運行時候自動加載
- */
- @Override
- public void contextInitialized(ServletContextEvent arg0) {
- /**
- * 設置一個定時器
- */
- timer = new java.util.Timer(true);
- arg0.getServletContext().log("定時器已啟動");
- /**
- * 定時器到指定的時間時,執行某個操作(如某個類,或方法)
- */
- //設置執行時間
- Calendar calendar =Calendar.getInstance();
- int year = calendar.get(Calendar.YEAR);
- int month = calendar.get(Calendar.MONTH);
- int day =calendar.get(Calendar.DAY_OF_MONTH);//每天
- //定制每天的1:00:00執行,
- calendar.set(year, month, day, 01, 00, 00);
- Date date = calendar.getTime();
- // System.out.println(date);
- int period = 24 * 60 * 60 * 1000;
- //每天的date時刻執行task,每隔persion 時間重復執行
- timer.schedule(new DelFileTask(arg0.getServletContext()), date, period);
- // 在 指定的date時刻執行task, 僅執行一次
- // timer.schedule(new DelFileTask(arg0.getServletContext()), date);
- arg0.getServletContext().log("已經添加任務調度表");
- }
- /**
- * 銷毀
- */
- @Override
- public void contextDestroyed(ServletContextEvent arg0){
- timer.cancel();
- arg0.getServletContext().log("定時器銷毀");
- }
- }
任務類 監聽器類 都實現了 下一步就是在web.xml 配置監聽器了
- <listener>
- <listener-class>com.sxl.ContextListener</listener-class>
- </listener>
到了這里 一個簡單的定時器基本上實現了 也能跑通了 接下來 需要做的 就是根據自己項目的實際要求 去豐富定時器類 DelFileTask 和啟動定時器的ContextListener 。
java.util.Timer 類的 schedule方法說明
schedule(TimerTask task, long delay)
-
安排在指定延遲后執行指定的任務。 (只執行一次)
-
- 參數:
-
task- 所要安排的任務。 -
delay- 執行任務前的延遲時間,單位是毫秒。 - 拋出:
-
IllegalArgumentException- 如果 delay 是負數,或者 delay + System.currentTimeMillis() 是負數。 -
IllegalStateException- 如果已經安排或取消了任務,或者已經取消計時器。
schedule(TimerTask task, Date time)
-
安排在指定的時間執行指定的任務。如果此時間已過去,則安排立即執行該任務。 (只執行一次)
-
- 參數:
-
task- 所要安排的任務。 -
time- 執行任務的時間。 - 拋出:
-
IllegalArgumentException- 如果 time.getTime() 是負數。 -
IllegalStateException- 如果已經安排或取消了任務,已經取消了計時器,或者計時器線程已終止。
schedule(TimerTask task,long delay, long period)
-
安排指定的任務從指定的延遲后開始進行重復的
固定延遲執行。以近似固定的時間間隔(由指定的周期分隔)進行后續執行。
在固定延遲執行中,根據前一次執行的實際執行時間來安排每次執行。如果由於任何原因(如垃圾回收或其他后台活動)而延遲了某次執行,則后續執行也將被延遲。從長期來看,執行的頻率一般要稍慢於指定周期的倒數(假定Object.wait(long) 所依靠的系統時鍾是准確的)。
固定延遲執行適用於那些需要“平穩”運行的重復活動。換句話說,它適用於在短期運行中保持頻率准確要比在長期運行中更為重要的活動。這包括大多數動畫任務,如以固定時間間隔閃爍的光標。這還包括為響應人類活動所執行的固定活動,如在按住鍵時自動重復輸入字符。
-
- 參數:
-
task- 所要安排的任務。 -
delay- 執行任務前的延遲時間,單位是毫秒。 -
period- 執行各后續任務之間的時間間隔,單位是毫秒。 - 拋出:
-
IllegalArgumentException- 如果 delay 是負數,或者 delay + System.currentTimeMillis() 是負數。 -
IllegalStateException- 如果已經安排或取消了任務,已經取消了計時器,或者計時器線程已終止。
schedule(TimerTask task, Date firstTime, long period)
-
安排指定的任務在指定的時間開始進行重復的
固定延遲執行。以近似固定的時間間隔(由指定的周期分隔)進行后續執行。
在固定延遲執行中,根據前一次執行的實際執行時間來安排每次執行。如果由於任何原因(如垃圾回收或其他后台活動)而延遲了某次執行,則后續執行也將被延遲。在長期運行中,執行的頻率一般要稍慢於指定周期的倒數(假定Object.wait(long) 所依靠的系統時鍾是准確的)。
固定延遲執行適用於那些需要“平穩”運行的重復執行活動。換句話說,它適用於在短期運行中保持頻率准確要比在長期運行中更為重要的活動。這包括大多數動畫任務,如以固定時間間隔閃爍的光標。這還包括為響應人類活動所執行的固定活動,如在按住鍵時自動重復輸入字符。
-
- 參數:
-
task- 所要安排的任務。 -
firstTime- 首次執行任務的時間。 -
period- 執行各后續任務之間的時間間隔,單位是毫秒。 - 拋出:
-
IllegalArgumentException- 如果 time.getTime() 是負數。 -
IllegalStateException- 如果已經安排或取消了任務,已經取消了計時器,或者計時器線程已終止。
參考文章 :http://blog.csdn.net/xiaojin21cen/article/details/7725565
