首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Web 應用定時任務輕量實作:ServletContextListener + Timer/TimerTask 完整方案

     編輯:Java 程式設計入門

在 Web 容器中實現定時排程,除引入 Quartz 等重型框架外,Java 標準庫 java.util.Timer 與 TimerTask 配合 ServletContextListener 即可構建零依賴的輕量級方案。本文提供完整三步驟實作範本。

架構設計

  • TaskManager:實作 ServletContextListener,容器啟動時初始化 Timer、註冊排程;關閉時銷毀 Timer。
  • 具體任務類別:繼承 TimerTask,實作 run() 業務邏輯,含併發保護機制。
  • web.xml 註冊:宣告 Listener 啟動鏈路。

完整程式碼實作

1. 任務管理器

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 = 0L;

    private Timer timer;

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        timer = new Timer("DB-Backup-Timer", true); // Daemon 執行緒
        // 每 4 週(約一月)執行一次備份
        timer.schedule(new BackUpTableTask(), NO_DELAY, PERIOD_WEEK * 4);
        // 測試用:每 30 秒執行一次
        // timer.schedule(new BackUpTableTask(), NO_DELAY, 30_000);
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        timer.cancel(); // 釋放 Timer 執行緒與排程
    }
}

2. 備份任務實作(含重入防護)

public class BackUpTableTask extends TimerTask {
    private static final Log LOG = LogFactory.getLog(BackUpTableTask.class);
    private static volatile boolean isRunning = false;

    @Override
    public void run() {
        if (!isRunning) {
            isRunning = true;
            try {
                LOG.debug("開始執行資料庫備份任務...");
                // TODO: 實際備份邏輯(呼叫 Service/DAO)
                // backupService.executeFullBackup();
                LOG.debug("資料庫備份任務完成.");
            } catch (Exception e) {
                LOG.error("備份任務異常", e);
            } finally {
                isRunning = false;
            }
        } else {
            LOG.warn("上一次備份任務尚未結束,跳過本次排程.");
        }
    }
}

3. web.xml 註冊

<listener>
    <listener-class>com.example.task.TaskManager</listener-class>
    <description>資料庫定時備份任務</description>
</listener>

關鍵設計考量

議題處理策略
併發重入 volatile boolean isRunning 雙重檢查,避免長任務重疊執行
例外隔離 run() 內部 try-catch 吞併例外,防止單次失敗導致 Timer 執行緒終止
Daemon 執行緒 new Timer(name, true) 標記為守護執行緒,不阻塞 JVM 關閉
資源釋放 contextDestroyed 呼叫 timer.cancel() 清理排程佇列
叢集環境 單機方案;叢集需引入 Quartz + JDBC JobStore 或分散式排程平台

適用場景與限制

  • ✅ 輕量級專案、原型開發、單機部署、簡單週期性維護任務(備份、報表、清理)。
  • ❌ 高可用性要求、叢集環境、複雜排程表達式(Cron)、任務持久化/監控/管理介面需求 → 改用 Quartz、Spring @Scheduled + Quartz、xxl-job 等專業框架。

善用標準庫解決簡單問題,是工程師務實取捨的體現。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved