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

Java Timer 與 TimerTask 實戰:從基礎排程到通用排程框架設計

     編輯:Java 相關知識

Timer 框架基本架構

java.util.Timer(排程器)+ java.util.TimerTask(任務單元)構成 Java 內建排程框架(J2SE 1.3+、J2ME 亦支援)。核心機制:單一背景執行緒循序執行所有任務。

基礎用法:一次性任務(煮蛋計時器)


public class EggTimer {
    private final Timer timer = new Timer();
    private final int minutes;

    public EggTimer(int minutes) { this.minutes = minutes; }

    public void start() {
        timer.schedule(new TimerTask() {
            @Override public void run() {
                playSound();
                timer.cancel(); // 單次任務執行完關閉 Timer
            }
            private void playSound() {
                System.out.println("Your egg is ready!");
            }
        }, minutes * 60 * 1000L); // 延遲毫秒
    }

    public static void main(String[] args) {
        new EggTimer(2).start(); // 2 分鐘後提醒
    }
}

Timer 核心 API 速查

方法用途參數說明
schedule(task, delay)一次性任務delay:延遲毫秒
schedule(task, time)指定時間一次性time:Date 物件
schedule(task, delay, period)固定延遲週期執行上次執行結束後 delay 再執行,適合頻率不嚴格場景
scheduleAtFixedRate(task, delay, period)固定頻率週期執行嚴格按時間軸間隔,適合精確排程(如每分鐘備份)
schedule(task, firstTime, period)指定首次時間 + 週期firstTime:Date

Timer 的三大痛點

  1. 單執行緒阻塞:某任務耗時/拋出例外 → 後續任務延遲或停止。
  2. 無法處理夏令時/系統時間調整:scheduleAtFixedRate 依賴系統時間,時間跳躍會導致任務重複或漏跑。
  3. 缺乏持久化、叢集、監控、動態增減:企業級排程需求無法滿足。

進階:構建通用排程框架(核心思想)

文章提出兩類別 + 一介面的輕量框架:

  • Scheduler:統一入口,管理任務註冊、啟動、關閉。
  • ScheduleTask:擴充 TimerTask,增加任務 ID、描述、下次執行時間計算邏輯。
  • Trigger 介面:nextExecutionTime() 定義複雜排程規則(每日固定時間、每月最後一天、工作日、Cron 表達式等)。

關鍵設計點


public interface Trigger {
    Date nextExecutionTime(Date lastExecutionTime);
}

// 範例:每日固定時間觸發器
public class DailyTrigger implements Trigger {
    private final int hour, minute;
    public DailyTrigger(int hour, int minute) { this.hour = hour; this.minute = minute; }
    @Override
    public Date nextExecutionTime(Date last) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(last != null ? last : new Date());
        cal.set(Calendar.HOUR_OF_DAY, hour);
        cal.set(Calendar.MINUTE, minute);
        cal.set(Calendar.SECOND, 0);
        if (!cal.getTime().after(last)) cal.add(Calendar.DAY_OF_MONTH, 1);
        return cal.getTime();
    }
}

生產環境建議:別再手寫排程框架了

除非極簡場景(單機、無持久化需求),否則直接上成熟方案:

框架特點適用場景
Spring @Scheduled輕量、整合 Spring、支援 Cron/固定頻率單體應用、簡單定時任務
Quartz功能豐富、叢集、持久化、Cron、監聽器企業級、需高可用、動態管理
XXL-JOB分散式、Web 控制台、分片廣播、故障轉移微服務、多節點、運維友好
PowerJob新生代、高效能、支援工作流、多語言大規模、複雜依賴、雲原生

總結

Timer 適合「單機、簡單、非關鍵」排程。理解其單執行緒模型與時間跳躍缺陷,是避坑關鍵。需要「每天固定時間、夏令時安全、叢集高可用」時,請毫不猶豫選用 Quartz 或 XXL-JOB,專注業務而非造輪子。

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