Java 中的定時調度由 java.util.Timer(調度器)與 java.util.TimerTask(任務單元)協作完成。Timer 內部維護單一後台線程循序執行所有任務,線程安全但吞吐受限;TimerTask 為抽象類,子類需重寫 run() 實現業務邏輯。
| 方法 | 說明 | 特點 |
|---|---|---|
schedule(task, delay) |
延遲指定時間後單次執行 | 固定延遲,執行時間受前任務影響 |
schedule(task, delay, period) |
延遲後按固定間隔重複執行 | 強調間隔穩定,前任務超時會推遲後續 |
scheduleAtFixedRate(task, delay, period) |
延遲後按固定頻率執行 | 強調頻率穩定,前任務超時會並發追趕 |
public class DelayTaskDemo {
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override public void run() {
System.out.println("3 秒後觸發:" + new Date());
}
}, 3000);
}
}
public class FixedTimeDemo {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 11);
cal.set(Calendar.MINUTE, 39);
cal.set(Calendar.SECOND, 0);
new Timer().schedule(new TimerTask() {
@Override public void run() {
System.out.println("每日 11:39 執行:" + new Date());
}
}, cal.getTime(), 24 * 60 * 60 * 1000); // 每天重複
}
}
public class RateVsDelayDemo {
public static void main(String[] args) {
Timer timer = new Timer();
long start = System.currentTimeMillis();
// 固定延遲:任務耗時 4s,間隔 2s → 實際間隔變 4s
timer.schedule(new TimerTask() {
@Override public void run() {
System.out.println("FixedDelay 執行:" + (System.currentTimeMillis() - start));
sleep(4000);
}
}, 1000, 2000);
// 固定頻率:任務耗時 4s,間隔 2s → 會嘗試追趕,導致並發執行
timer.scheduleAtFixedRate(new TimerTask() {
@Override public void run() {
System.out.println("FixedRate 執行:" + (System.currentTimeMillis() - start));
sleep(4000);
}
}, 3000, 2000);
}
static void sleep(long ms) {
try { Thread.sleep(ms); } catch (InterruptedException ignored) {}
}
}
TimerTask 拋出未檢查異常會終止 Timer 線程,所有已排程任務永不執行,新任務也無法調度。基於線程池,支援並發調度、異常隔離、絕對時間調度,完美解決上述痛點:
ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
// 異常隔離演示:task1 拋異常不影響 task2
executor.schedule(() -> { throw new RuntimeException("任務1炸了"); }, 1, TimeUnit.SECONDS);
executor.scheduleAtFixedRate(() -> System.out.println("任務2持續運行:" + new Date()), 2, 500, TimeUnit.MILLISECONDS);
ScheduledThreadPoolExecutor 或 Spring @Scheduled/Quartz。