在 Java Web 應用中,若需實現簡單的定時任務(如定期備份數據庫、發送報表、清理臨時文件),引入 Quartz 等重型調度框架可能大材小用。JDK 內建的 java.util.Timer 和 java.util.TimerTask 提供了零依賴、輕量級的解決方案,配合 ServletContextListener 即可在 Web 容器啟動/關閉時自動管理任務生命週期。
public class TaskManager implements ServletContextListener {
private static final long PERIOD_DAY = 24 * 60 * 60 * 1000L; // 一天毫秒數
private static final long PERIOD_WEEK = PERIOD_DAY * 7; // 一周毫秒數
private static final long NO_DELAY = 0;
private Timer timer;
@Override
public void contextInitialized(ServletContextEvent event) {
timer = new Timer("資料庫備份任務", true); // true 表示守護線程
// 每 4 週(約一月)執行一次備份
timer.schedule(new BackUpTableTask(), NO_DELAY, PERIOD_WEEK * 4);
// 測試用:每 30 秒執行一次
// timer.schedule(new BackUpTableTask(), NO_DELAY, 30_000);
}
@Override
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; // 防止並發重入
@Override
public void run() {
if (!isRunning) {
isRunning = true;
try {
log.debug("開始執行備份任務...");
// 此處編寫實際業務邏輯:備份數據庫、發送郵件等
log.debug("備份任務執行完成...");
} finally {
isRunning = false;
}
} else {
log.debug("上一次任務尚未結束,跳過本次執行...");
}
}
}
<listener>
<listener-class>com.example.TaskManager</listener-class>
<description>定期執行資料庫備份任務</description>
</listener>
new Timer(name, true) 確保容器關閉時定時器線程不會阻塞 JVM 退出isRunning 標誌防止任務執行時間超過間隔導致重疊執行run() 方法中務必捕獲異常,否則定時器會終止後續所有任務Timer + TimerTask + ServletContextListener 是 Java Web 輕量級定時任務的經典組合,零第三方依賴、配置簡單、啟停自動,極適合中小型專案的定期維護類任務。