Timer 基礎用法
import java.util.Timer;
import java.util.TimerTask;
public class TimerDemo {
public static void main(String[] args) {
Timer timer = new Timer();
// 1秒後首次執行,之後每2秒執行一次
timer.schedule(new TimerTask() {
@Override public void run() { System.out.println("Task running..."); }
}, 1000, 2000);
// 模擬主線程等待用戶輸入 'c' 取消
new Thread(() -> {
try { System.in.read(); timer.cancel(); } catch (Exception ignored) {}
}).start();
}
}
兩種調度模式對比
| 方法 | 特點 | 適用場景 |
schedule(task, delay, period) | 固定延遲:下次執行時間 = 上次執行完成時間 + period。若任務耗時長,間隔會拉大。 | 間隔敏感度低、任務耗時不可預測 |
scheduleAtFixedRate(task, delay, period) | 固定頻率:下次執行時間 = 上次計劃開始時間 + period。若任務延遲,會嘗試趕工(連續執行)追回進度。 | 需要嚴格週期性(如每秒採集數據) |
進階示例:動態修改任務信息與選擇性取消
public class AdvancedTimerDemo {
static class MyTask extends TimerTask {
String info = "^_^";
public void run() { System.out.println(info); }
public void setInfo(String info) { this.info = info; }
}
public static void main(String[] args) throws IOException {
Timer timer = new Timer();
MyTask task1 = new MyTask();
MyTask task2 = new MyTask(); task2.setInfo("Task-2");
timer.schedule(task1, 1000, 2000);
timer.scheduleAtFixedRate(task2, 2000, 3000);
// 控制台交互取消
byte[] buf = new byte[1024];
while (true) {
int len = System.in.read(buf);
String cmd = new String(buf, 0, len).trim();
if ("Cancel-1".equals(cmd)) task1.cancel();
else if ("Cancel-2".equals(cmd)) task2.cancel();
else if ("Cancel-All".equals(cmd)) { timer.cancel(); break; }
else task1.setInfo(cmd); // 動態修改 task1 輸出內容
}
}
}
注意事項
Timer 單線程串行執行所有任務,某任務阻塞會延遲後續任務。
- 生產環境建議使用
ScheduledExecutorService(線程池、異常處理更完善)。
TimerTask.cancel() 僅取消該任務;Timer.cancel() 取消所有任務並終止計時器線程。
- JDK 5+ 推薦
scheduleAtFixedRate 實現平滑週期執行。