Java 定時任務核心由兩個類別組成:
run() 方法定義具體執行邏輯| 方法 | 特性 | 適用場景 |
|---|---|---|
schedule(task, delay, period) | 固定延遲執行 上次執行結束 → 等待 period → 下次執行 | 頻率固定、允許執行時間漂移的一般性任務 |
scheduleAtFixedRate(task, delay, period) | 固定頻率執行 按理論時間點觸發,若延遲則追趕執行 | 需精確時間點觸發的任務(如每整點備份) |
package com.bjpowernode.test;
import java.io.IOException;
import java.util.Timer;
public class TimerTest {
public static void main(String[] args) {
Timer timer = new Timer();
// 1秒後啟動,每2秒執行一次
timer.schedule(new MyTask(), 1000, 2000);
// 主執行緒等待使用者輸入 's' 停止
System.out.println("輸入 's' 停止定時器...");
while (true) {
try {
int in = System.in.read();
if (in == 's') {
timer.cancel(); // 終止所有任務
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
static class MyTask extends TimerTask {
@Override
public void run() {
System.out.println("________ " + new java.util.Date());
}
}
}
timer.cancel() → 程式結束package com.bjpowernode.test;
import java.io.IOException;
import java.util.Date;
import java.util.Timer;
public class TimerTest2 {
public static void main(String[] args) {
Timer timer = new Timer();
MyTask task1 = new MyTask();
MyTask task2 = new MyTask();
task2.setInfo("task2-特殊標識");
// 任務1:固定延遲模式 - 1秒後啟動,每2秒執行
timer.schedule(task1, 1000, 2000);
// 任務2:固定頻率模式 - 2秒後啟動,每3秒執行
timer.scheduleAtFixedRate(task2, 2000, 3000);
// 互動式控制台
System.out.println("指令: Cancel-1 | Cancel-2 | Cancel-All | 自訂訊息");
while (true) {
try {
byte[] buf = new byte[1024];
int len = System.in.read(buf);
String cmd = new String(buf, 0, len, "GBK").trim();
if (cmd.endsWith("\r\n")) cmd = cmd.substring(0, cmd.length() - 2);
switch (cmd) {
case "Cancel-1":
task1.cancel();
System.out.println("任務1已取消");
break;
case "Cancel-2":
task2.cancel();
System.out.println("任務2已取消");
break;
case "Cancel-All":
timer.cancel();
System.out.println("定時器已完全關閉");
return;
default:
task1.setInfo(cmd); // 動態修改任務1輸出內容
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
static class MyTask extends TimerTask {
private String info = "INFO";
@Override
public void run() {
System.out.println(new Date() + " [" + info + "]");
}
public void setInfo(String info) { this.info = info; }
public String getInfo() { return info; }
}
}
| 類別 | 方法 | 功能 |
|---|---|---|
| Timer | cancel() | 終止定時器,捨棄所有已排程任務 |
purge() | 移除佇列中已取消的任務,釋放記憶體 | |
schedule(task, date) | 在指定時間單次執行 | |
schedule(task, delay) | 延遲指定毫秒後單次執行 | |
| TimerTask | cancel() | 取消此任務 (單次任務執行後自動取消) |
run() | 任務執行邏輯 (必須實作) | |
scheduledExecutionTime() | 取得最近一次實際排程執行時間 |
// 固定延遲:執行時間 = 上次結束時間 + period // 優點:間隔穩定;缺點:長期運行會時間漂移 timer.schedule(task, 0, 1000); // 固定頻率:執行時間 = 初始時間 + n * period // 優點:長期時間精準;缺點:若任務耗時 > period 會疊加執行 timer.scheduleAtFixedRate(task, 0, 1000);
run() 中未捕獲的異常會導致 Timer 執行緒終止,所有任務停止。務必使用 try-catch 包裹| 方案 | 優點 | 缺點 |
|---|---|---|
| Timer | 輕量、API 簡單、JDK 內建 | 單執行緒、異常脆弱、無持久化 |
| ScheduledExecutorService | 執行緒池、健壯、彈性關閉 | API 較複雜、無持久化 |
| Spring @Scheduled | 聲明式、整合 Spring 生命週期、支援 Cron | 需 Spring 容器、單機模式 |
| Quartz | 持久化、分散式、Cron 複雜排程 | 配置複雜、較重量級 |
Timer 作為 JDK 早期提供的定時工具,雖然功能基礎但概念清晰,適合簡單場景與教學用途。掌握其核心機制有助於理解更高階排程框架的設計哲學。