在 Web 應用中需定期執行任務 (如資料庫備份、報表生成),除引入 Quartz 等重型框架外,Java 內建 Timer 與 TimerTask 配合 ServletContextListener 即可輕鬆實現,零依賴、部署簡單。
public class TaskManager implements ServletContextListener {
public static final long PERIOD_DAY = 24 * 60 * 60 * 1000L;
public static final long PERIOD_WEEK = PERIOD_DAY * 7;
public static final long NO_DELAY = 0;
private Timer timer;
public void contextInitialized(ServletContextEvent event) {
timer = new Timer("資料庫表備份", true); // daemon thread
// 每 4 週 (約一個月) 執行一次
timer.schedule(new BackUpTableTask(), NO_DELAY, PERIOD_WEEK * 4);
// 測試用:每 30 秒執行
// timer.schedule(new BackUpTableTask(), NO_DELAY, 30000);
}
public void contextDestroyed(ServletContextEvent event) {
timer.cancel(); // 銷毀定時器
}
}
public class BackUpTableTask extends TimerTask {
private static final Log log = LogFactory.getLog(BackUpTableTask.class);
private static boolean isRunning = false;
public void run() {
if (!isRunning) {
isRunning = true;
log.debug("開始執行任務...");
// TODO: 實際業務邏輯 (備份、清理等)
log.debug("執行任務完成...");
isRunning = false;
} else {
log.debug("上一次任務執行尚未結束...");
}
}
}
isRunning 旗標防止任務重疊執行,確保同一時間僅有一個實例運行。
<listener>
<listener-class>com.example.TaskManager</listener-class>
<description>定期執行的備份任務</description>
</listener>
contextInitialized → 建立 Timer 並排程任務TimerTask.run()contextDestroyed → 取消 Timer,優雅關閉| 優點 | 缺點 |
|---|---|
| 零第三方依賴、代碼量極少、容易理解與維護 | 無持久化排程、叢集環境下會重複執行、無誤火處理、無管理介面 |
適用於:單機部署、簡單週期性任務、不需高可用性排程的中小型專案。若需叢集、持久化、彈性排程表達式 (Cron)、監控管理,請改用 Quartz 或 Spring Task。