java.util.Timer 是 Java 標準庫中用於排程任務的基礎工具類,適用於在指定時間或固定間隔執行任務。它是線程安全的,但不提供實時性保證,即任務執行時間可能因系統負載或 GC 而延遲。Timer 內部維護一條背景執行緒,所有排程任務共享此執行緒,因此長時間運行的任務會阻塞後續任務。
Timer():預設建構子,建立非守護執行緒。Timer(boolean isDaemon):指定關聯執行緒是否為 daemon 執行緒(JVM 退出時不阻塞)。Timer(String name):指定執行緒名稱,便於除錯與監控。Timer(String name, boolean isDaemon):同時指定名稱與守護屬性。schedule(TimerTask task, long delay):延遲 delay 毫秒後執行一次。schedule(TimerTask task, Date time):在指定日期執行一次;若時間已過則立即執行。後續執行時間參考「上一次任務實際開始時間」計算,任務耗時過長不會補償。
schedule(TimerTask task, long delay, long period)schedule(TimerTask task, Date firstTime, long period)後續執行時間參考「上一次任務理論開始時間」計算,若任務延遲會嘗試補償(追趕執行)。
scheduleAtFixedRate(TimerTask task, long delay, long period)scheduleAtFixedRate(TimerTask task, Date firstTime, long period)| 場景 | schedule (fixed-delay) | scheduleAtFixedRate (fixed-rate) |
|---|---|---|
| 任務未延遲 | 參考上次開始時間 | 參考上次開始時間 |
| 任務延遲且首次時間已過 | 參考上次結束時間 | 先補償(參考結束時間),補償完畢後參考開始時間 |
| 任務延遲且首次時間未到 | 參考上次結束時間 | 參考上次結束時間 |
public class TimerDemo {
private static Timer timer = new Timer("DemoTimer", true);
public static void main(String[] args) throws ParseException {
TimerTask task = new TimerTask() {
@Override public void run() {
System.out.println("Run Time: " + new Date());
}
};
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sdf.parse("2025-12-27 14:36:00");
timer.schedule(task, date);
}
}
timer.schedule(new TimerTask() {
@Override public void run() {
System.out.println("Run Time: " + new Date());
}
}, 3000, 5000); // 延遲 3s,每 5s 執行一次
timer.scheduleAtFixedRate(new TimerTask() {
@Override public void run() {
System.out.println("Run Time: " + new Date());
}
}, 3000, 5000);
當 TimerTask.run() 耗時超過 period 時:
TimerTask 中執行耗時操作;若必要,改用 ScheduledExecutorService(支援執行緒池)。run() 內部異常,防止單一任務失敗導致整個 Timer 執行緒終止。timer.cancel() 釋放資源。