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

Java 定時任務實戰:每日定點執行與服務重啟保護機制

     編輯:Java 程式設計入門

核心需求:每日固定時間自動執行任務

本文通過完整代碼示例,演示如何使用 Timer 與 TimerTask 實現每日凌晨 2 點自動執行業務邏輯,並解決服務重啟導致任務立即執行的經典問題。

核心調度器:TimerManager

public class TimerManager {
    private static final long PERIOD_DAY = 24 * 60 * 60 * 1000; // 24小時毫秒數

    public TimerManager() {
        Calendar calendar = Calendar.getInstance();
        
        // 設定每日 02:00:00 執行
        calendar.set(Calendar.HOUR_OF_DAY, 2);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        
        Date firstRunTime = calendar.getTime();
        
        // 關鍵邏輯:若首次執行時間早於當前時間,順延一天
        if (firstRunTime.before(new Date())) {
            firstRunTime = addDay(firstRunTime, 1);
        }
        
        Timer timer = new Timer();
        NFDFlightDataTimerTask task = new NFDFlightDataTimerTask();
        // 安排任務:首次執行 firstRunTime,之後每 PERIOD_DAY 執行一次
        timer.schedule(task, firstRunTime, PERIOD_DAY);
    }

    // 日期加減工具方法
    public Date addDay(Date date, int days) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DAY_OF_MONTH, days);
        return cal.getTime();
    }
}

避坑指南:服務重啟時間點判斷

若服務在凌晨 2 點後啟動(如 3 點),firstRunTime (2點) 會早於當前時間,若不處理,任務會立即執行而非等待次日。代碼中的 if (date.before(new Date())) 判斷正是為此:檢測到時間已過,自動將首次執行時間順延 24 小時,確保任務在次日 2 點準時運行。

任務邏輯實現:NFDFlightDataTimerTask

public class NFDFlightDataTimerTask extends TimerTask {
    private static Logger log = Logger.getLogger(NFDFlightDataTimerTask.class);

    @Override
    public void run() {
        try {
            // 在此編寫具體業務邏輯
            // 例如:數據同步、報表生成、緩存刷新等
        } catch (Exception e) {
            log.info("-------------解析信息發生異常--------------");
        }
    }
}

Web 容器啟動監聽器:自動啟動調度器

public class NFDFlightDataTaskListener implements ServletContextListener {
    public void contextInitialized(ServletContextEvent event) {
        new TimerManager(); // 容器啟動時自動初始化定時任務
    }
    public void contextDestroyed(ServletContextEvent event) {
        // 容器關閉時可執行清理工作
    }
}

web.xml 配置監聽器

<listener>
    <listener-class>
        com.listener.NFDFlightDataTaskListener
    </listener-class>
</listener>

生產環境建議

  • 單機部署:上述方案完全適用
  • 集群部署:需引入分佈式調度框架(如 Quartz + 數據庫鎖、XXL-JOB、Elastic-Job)防止多節點重複執行
  • 異常處理:run() 方法必須捕獲所有異常,否則 Timer 線程會終止,導致後續任務不再執行
  • 長任務:若任務執行時間超過間隔周期,建議使用 ScheduledThreadPoolExecutor 替代 Timer
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved